From bc864d29786ab8c203506018efb2f4d462fc2d5f Mon Sep 17 00:00:00 2001 From: Kenneth Kasilag Date: Wed, 3 Jun 2026 08:04:02 +0000 Subject: [PATCH] airoha: use kernel 6.18 by default and drop 6.12 Switch the airoha target to use kernel 6.18 and drop 6.12. This removes a large amount of patches that have since been merged to upstream; and removes the build system hack used to support building 6.12 and 6.18 with a slightly different DTS and package configuration. Signed-off-by: Kenneth Kasilag Link: https://github.com/openwrt/openwrt/pull/23640 Signed-off-by: Jonas Jelonek --- target/linux/airoha/Makefile | 3 +- .../an7581/base-files/etc/init.d/airoha_fan | 2 +- target/linux/airoha/an7581/config-6.12 | 387 - target/linux/airoha/an7583/config-6.12 | 375 - .../airoha/dts/an7581-w1700k-ubi-618.dts | 15 - target/linux/airoha/dts/an7581-w1700k-ubi.dts | 8 +- target/linux/airoha/en7523/config-6.12 | 313 - target/linux/airoha/image/an7581.mk | 19 +- ...EGRESS_RATE_METER_EN_MASK-definition.patch | 33 - ...emove-unnecessary-restriction-length.patch | 33 - ...e-unnecessary-switch-to-non-dma-mode.patch | 30 - ...-airoha-unify-dirmap-read-write-code.patch | 137 - ...rt-of-dualio-quadio-flash-reading-co.patch | 94 - ...-setting-of-page-oob-sizes-in-REG_SP.patch | 64 - ...e-the-number-of-modification-of-REG_.patch | 199 - ...ustom-sector-size-equal-to-flash-pag.patch | 142 - ...-reading-flash-page-settings-from-SN.patch | 206 - ...uffer-must-be-0xff-ed-before-writing.patch | 32 - ...arm-dts-airoha-en7523-add-SNAND-node.patch | 40 - ...a-add-support-for-Airoha-EN7581-TRNG.patch | 306 - ...13-net-airoha-Simplify-Tx-napi-logic.patch | 130 - ...d-support-for-Airoha-EN7851-watchdog.patch | 267 - ...en7581_reset_register-in-en7581_clk_.patch | 174 - ...7523-map-io-region-in-a-single-block.patch | 84 - ...rl-airoha-Add-support-for-EN7581-SoC.patch | 3060 -------- ...oha-Use-unsigned-long-for-bit-search.patch | 61 - ...ypo-in-REG_CDM2_FWD_CFG-configuratio.patch | 35 - ...e-Tx-drop-capability-for-each-Tx-DMA.patch | 27 - ...-Introduce-ndo_select_queue-callback.patch | 86 - ...airoha-Add-sched-ETS-offload-support.patch | 292 - ...airoha-Add-sched-HTB-offload-support.patch | 371 - ...roha-Add-EN7581-CPUFreq-SMCCC-driver.patch | 232 - ...net-airoha-Enforce-ETS-Qdisc-priomap.patch | 53 - ...oha-Add-Airoha-CPU-PM-Domain-support.patch | 196 - ...k-clock-handling-for-different-clock.patch | 83 - ...ck-drop-NUM_CLOCKS-define-for-EN7581.patch | 26 - ...ngs-clock-add-ID-for-eMMC-for-EN7581.patch | 25 - ...en7523-Add-clock-for-eMMC-for-EN7581.patch | 41 - ...3-Rely-on-clk_bulk_prepare_enable-in.patch | 57 - ...3-Move-reset-assert-callbacks-in-.po.patch | 86 - ...3-Add-comment-about-initialization-o.patch | 35 - ...3-Move-reset-delay-in-mtk_pcie_en758.patch | 59 - ...3-Rely-on-msleep-in-mtk_pcie_en7581_.patch | 41 - ...3-Avoid-PCIe-resetting-via-PERST-for.patch | 128 - ...3-Remove-leftover-mac_reset-assert-f.patch | 34 - ...3-Configure-PBUS_CSR-registers-for-E.patch | 81 - ...x-TSO-support-for-header-cloned-skbs.patch | 60 - ...oha-Reset-BQL-stopping-the-netdevice.patch | 42 - ...airoha_eth-driver-in-a-dedicated-fol.patch | 6863 ----------------- ...oha-Move-definitions-in-airoha_eth.h.patch | 538 -- ...reg-write-utility-routines-in-airoha.patch | 101 - ...register-definitions-in-airoha_regs..patch | 1361 ---- ...iroha-Move-DSA-tag-in-DMA-descriptor.patch | 287 - ...t7530-Enable-Rx-sptag-for-EN7581-SoC.patch | 46 - ...ble-support-for-multiple-net_devices.patch | 144 - ...REG_GDM_FWD_CFG-initialization-in-ai.patch | 77 - ...e-airoha_set_gdm_port_fwd_cfg-in-air.patch | 120 - ...-airoha-Introduce-Airoha-NPU-support.patch | 627 -- ...-Introduce-flowtable-offload-support.patch | 1481 ---- ...airoha-Add-loopback-support-for-GDM2.patch | 210 - ...airoha-Introduce-PPE-debugfs-support.patch | 291 - ...Add-support-for-Airoha-EN7581-therma.patch | 550 -- ...-drivers-airoha-Fix-spelling-mistake.patch | 44 - ...ix-wrong-PHY-LED-mapping-and-PHY2-LE.patch | 435 -- ...min-max-packet-len-configuration-in-.patch | 59 - ...-net-airoha-Enable-Rx-Scatter-Gather.patch | 170 - ...oduce-airoha_dev_change_mtu-callback.patch | 47 - ...15-net-airoha-Increase-max-mtu-to-9k.patch | 26 - ...an4-support-in-airoha_qdma_get_gdm_p.patch | 29 - ...able-TSO-Scatter-Gather-for-LAN-port.patch | 27 - ...ev-dsa_ptr-check-in-airoha_get_dsa_t.patch | 47 - ...net-airoha-fix-CONFIG_DEBUG_FS-check.patch | 35 - ...id-report-in-airoha_tc_get_htb_get_l.patch | 77 - ...et-airoha-Fix-ETS-priomap-validation.patch | 58 - ...ate-egress-gdm-port-in-airoha_ppe_fo.patch | 100 - ...6-net-airoha-Add-l2_flows-rhashtable.patch | 207 - ...iroha-Add-L2-hw-acceleration-support.patch | 253 - ...-Add-matchall-filter-offload-support.patch | 405 - ...oha-Introduce-airoha_irq_bank-struct.patch | 292 - ...e-multiple-IRQ-lines-support-in-airo.patch | 379 - ...issing-field-to-ppe_mbox_data-struct.patch | 48 - ...age-recycling-in-airoha_qdma_rx_proc.patch | 72 - ...ove-memory-allocation-in-airoha_npu_.patch | 196 - ...-Add-FLOW_CLS_STATS-callback-support.patch | 633 -- ...-airoha-ppe-Disable-packet-keepalive.patch | 28 - ...t-store-hfwd-references-in-airoha_qd.patch | 57 - ...he-capability-to-allocate-hwfd-buffe.patch | 79 - ...he-capability-to-allocate-hfwd-descr.patch | 82 - ...n-error-handling-path-in-airoha_allo.patch | 42 - ...itialize-PPE-UPDMEM-source-mac-table.patch | 122 - ...-IPv6-hw-acceleration-in-bridge-mode.patch | 64 - ...smac_id-configuration-in-bridge-mode.patch | 32 - ...net-airoha-Add-PPPoE-offload-support.patch | 87 - ...16-net-airoha-Enable-RX-queues-16-31.patch | 28 - ...s-check-return-value-from-airoha_ppe.patch | 32 - ...te-number-of-descriptors-according-t.patch | 77 - ...rentiate-hwfd-buffer-size-for-QDMA0-.patch | 64 - ...PE-table-access-in-airoha_ppe_debugf.patch | 92 - ...o-not-invalid-PPE-entries-in-case-of.patch | 42 - ...dd-NPU-wlan-memory-initialization-co.patch | 179 - ...dd-wlan_-send-get-_msg-NPU-callbacks.patch | 139 - ...pu-Add-wlan-irq-management-callbacks.patch | 74 - ...ead-NPU-wlan-interrupt-lines-from-th.patch | 58 - ...pu-Enable-core-3-for-WiFi-offloading.patch | 28 - ...t-airoha-Add-airoha_offload.h-header.patch | 416 - ...airoha-Add-wlan-flowtable-TX-offload.patch | 198 - ...on-airoha_eth-struct-in-airoha_ppe_f.patch | 95 - ...Add-airoha_ppe_dev-struct-definition.patch | 223 - ...duce-check_skb-callback-in-ppe_dev-o.patch | 207 - ...ix-return-value-in-pinconf-callbacks.patch | 50 - ...eplace-struct-function_desc-with-str.patch | 66 - ...-channel-configuration-for-ETS-Qdisc.patch | 36 - ...DIO-bus-controller-for-Airoha-AN7583.patch | 342 - ...ix-wrong-PHY-LED-mux-value-for-LED1-.patch | 68 - ...roha-fix-wrong-MDIO-function-bitmaks.patch | 58 - ...-Wflex-array-member-not-at-end-warni.patch | 45 - ...PE_IP_PROTO_CHK-register-definitions.patch | 29 - ...dd-a-NPU-callback-to-initialize-flow.patch | 159 - ...oopback-mode-configuration-for-GDM2-.patch | 43 - ...issing-stats-to-ethtool_eth_mac_stat.patch | 34 - ...airoha-Add-get_link-ethtool-callback.patch | 25 - ...into-account-out-of-order-tx-complet.patch | 54 - ...ynamically-allocate-foe_check_time-a.patch | 43 - ...iroha_ppe_get_num_stats_entries-and-.patch | 239 - ...iroha-Add-airoha_eth_soc_data-struct.patch | 152 - ...alize-airoha_ppe2_is_enabled-routine.patch | 147 - ...ove-PPE-memory-info-in-airoha_eth_so.patch | 359 - ...emove-airoha_ppe_is_enabled-where-no.patch | 58 - ...onfigure-SRAM-PPE-entries-via-the-cp.patch | 65 - ...lush-PPE-SRAM-table-during-PPE-setup.patch | 71 - ...t-default-ppe-cpu-port-in-airoha_dev.patch | 91 - ...tor-src-port-configuration-in-airhoh.patch | 202 - ...o-not-use-magic-numbers-in-airoha_pp.patch | 29 - ...19-net-airoha-Add-AN7583-SoC-support.patch | 185 - ...u-Add-missing-MODULE_FIRMWARE-macros.patch | 27 - ...-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch | 31 - ...a-npu-Add-airoha_npu_soc_data-struct.patch | 136 - ...-net-airoha-npu-Add-7583-SoC-support.patch | 56 - ...ve-code-duplication-in-airoha_regs.h.patch | 342 - ...n-error-handling-path-in-airoha_prob.patch | 29 - ...ha-Fix-a-copy-and-paste-bug-in-probe.patch | 37 - ...id-of-dma_sync_single_for_device-in-.patch | 40 - ...otential-use-after-free-in-airoha_np.patch | 41 - ...wm-airoha-Add-support-for-EN7581-SoC.patch | 689 -- ...he-capability-to-consume-out-of-orde.patch | 245 - ...eneralize-pins-group-function-confs-.patch | 775 -- ...airoha-convert-PHY-LED-GPIO-to-macro.patch | 635 -- ...trl-airoha-convert-PWM-GPIO-to-macro.patch | 492 -- ...a-add-support-for-Airoha-AN7583-PINs.patch | 969 --- ...t-loopback-traffic-to-GDM2-if-it-is-.patch | 31 - ...mt76-Introduce-the-NPU-generic-layer.patch | 34 - ...-fix-pinctrl-function-mismatch-issue.patch | 38 - ...ha-Fix-AIROHA_PINCTRL_CONFS_DRIVE_E2.patch | 40 - ...-hwrng-airoha-set-rng-quality-to-900.patch | 57 - ...et-airoha-Fix-npu-rx-DMA-definitions.patch | 34 - ...net_devs-registration-in-a-dedicated.patch | 89 - ...dm-port-enum-value-whenever-possible.patch | 132 - ...oha-npu-Dump-fw-version-during-probe.patch | 36 - ...chedule-while-atomic-in-airoha_ppe_d.patch | 41 - ...-airoha-implement-get_link_ksettings.patch | 26 - ...nit-BA-memory-region-if-provided-via.patch | 32 - ...ncrease-max-MTU-to-9220-for-DSA-jumb.patch | 37 - ...dd-the-capability-to-read-firmware-n.patch | 119 - ...net-airoha-fix-typo-in-function-name.patch | 53 - ...-__field_prep-for-non-constant-masks.patch | 44 - ...flow-control-source-port-mapping-dep.patch | 52 - ...GDM-forward-port-configuration-in-nd.patch | 86 - ...t-QDMA-block-according-LAN-WAN-confi.patch | 131 - ...ypo-in-airoha_ppe_setup_tc_block_cb-.patch | 32 - ...mediatek-enable-interrupts-on-AN7581.patch | 27 - ...-PPE-default-cput-port-in-airoha_ppe.patch | 162 - ...k-the-code-flow-in-airoha_remove-and.patch | 165 - ...-offloading-until-all-net_devices-ar.patch | 63 - ...ma_rmb-and-READ_ONCE-in-airoha_qdma_.patch | 78 - ...issing-PPE-configurations-in-airoha_.patch | 62 - ...E_PSE_BUF_SET-configuration-if-PPE2-.patch | 45 - ...emory-leak-in-airoha_qdma_rx_process.patch | 37 - ...Fix-VIP-configuration-for-AN7583-SoC.patch | 173 - ...on-net_device-pointer-in-airoha_dev_.patch | 64 - ...on-net_device-pointer-in-HTB-callbac.patch | 163 - ...on-net_device-pointer-in-ETS-callbac.patch | 118 - ...e-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch | 33 - ...ypo-in-airoha_set_gdm2_loopback-rout.patch | 35 - ...EG_RX_CPU_IDX-once-in-airoha_qdma_fi.patch | 34 - ...ndesc-initialization-at-end-of-airoh.patch | 55 - ...issing-bits-in-airoha_qdma_cleanup_t.patch | 73 - ...for-NPU-PPE-configuration-to-complet.patch | 63 - ...PE-cpu-port-configuration-for-GDM2-l.patch | 91 - ...ossible-TX-queue-stall-in-airoha_qdm.patch | 104 - ...ize-check-for-TX-NAPIs-in-airoha_qdm.patch | 57 - ...-airoha-fix-BQL-imbalance-in-TX-path.patch | 59 - ...net_device-TX-queue-before-updating-.patch | 46 - ...t-wake-all-netdev-TX-queues-in-airoh.patch | 75 - ...t-read-uninitialized-fragment-addres.patch | 64 - ...e-get_src_port_id-callback-in-get_sp.patch | 75 - ...-not-return-err-in-ndo_stop-callback.patch | 36 - ...entries-to-queue-head-in-case-of-DMA.patch | 38 - ...gure-QoS-channel-for-HW-accelerated-.patch | 44 - ...duce-airoha_fe_get-airoha_qdma_get-r.patch | 95 - ...ve-RX-headroom-to-avoid-skb-realloca.patch | 73 - ...le-GDM2-forwarding-before-configurin.patch | 45 - ...AFE-and-I2S-driver-for-Airoha-AN7581.patch | 1312 ---- ...ediatek-EIP-93-crypto-engine-support.patch | 4206 ---------- ...airoha-permit-GPIO43-46-for-PHY-LED0.patch | 101 - ...Add-bindings-for-Airoha-SCU-Serdes-l.patch | 35 - ...Add-documentation-for-Airoha-AN7581-.patch | 141 - ...PCIe-PHY-driver-to-dedicated-directo.patch | 1885 ----- ...dd-support-for-Airoha-AN7581-USB-PHY.patch | 667 -- ...d-ARCH_AIROHA-in-XHCI-MTK-dependency.patch | 25 - ...-gen3-set-PHY-mode-for-Airoha-EN7581.patch | 34 - ...-airoha-deassert-XSI-line-on-hw-init.patch | 26 - ...eference-for-SPORT-GDM4-in-qdma_get_.patch | 31 - ...nitial-fixup-for-GDM3-4-port-support.patch | 40 - ...7-airoha-ethernet-drop-xsi-mac-reset.patch | 33 - ...add-PCS-driver-for-Airoha-AN7581-SoC.patch | 4793 ------------ ...oha-add-phylink-support-for-GDM2-3-4.patch | 281 - ...16-net-dsa-mt7530-Add-AN7583-support.patch | 143 - ...thermal-airoha-convert-to-regmap-API.patch | 194 - ...ers-airoha-Generalize-probe-function.patch | 226 - ...airoha-generalize-get_thermal_ADC-an.patch | 129 - ...rivers-airoha-Add-support-for-AN7583.patch | 277 - ...eq-airoha-Add-support-for-AN7583-SoC.patch | 36 - ...-en7523-convert-driver-to-regmap-API.patch | 351 - ...-generalize-register-clocks-function.patch | 258 - ...onvert-to-full-clk_hw-implementation.patch | 147 - ...clk-en7523-add-support-for-.set_rate.patch | 173 - ...t-to-reference-Chip-SCU-from-phandle.patch | 37 - ...reword-and-clean-clk_probe-variables.patch | 53 - ...23-add-support-for-probing-SCU-child.patch | 57 - ...k-airoha-Document-support-for-AN7583.patch | 122 - ...-add-support-for-Airoha-AN7583-clock.patch | 328 - ...k-airoha-Add-reset-support-to-EN7523.patch | 100 - ...eset-controller-support-for-EN7523-S.patch | 177 - ...update-EN7523-dtsi-to-support-resets.patch | 32 - ...et-pcs-airoha-add-support-for-AN7583.patch | 3386 -------- ...t-airoha-define-sport-value-for-GDM3.patch | 26 - ...dd-support-for-optional-xfi-reset-li.patch | 63 - ...le-external-phy-code-if-PCS_AIROHA-i.patch | 124 - ...-add-PHY_DETACH_NO_HW_RESET-PHY-flag.patch | 129 - ...1xxx-add-flag-PHY_DETACH_NO_HW_RESET.patch | 108 - ...handle-corner-case-with-link-and-aut.patch | 31 - ...21xxx-fix-read_status-speed-handling.patch | 156 - ...hy-as21xxx-force-C45-OPs-for-AUTONEG.patch | 34 - ...implement-read-workaround-for-C45-re.patch | 132 - .../885-i2c-mt7621-optional-reset.patch | 11 - .../886-uart-add-en7523-support.patch | 206 - .../patches-6.12/900-airoha-bmt-support.patch | 578 -- .../901-snand-mtk-bmt-support.patch | 34 - ...rate-PERST-from-refclk-in-PCIe-clock.patch | 42 - ...dd-x2-link-support-for-Airoha-EN7581.patch | 244 - ...owtable-Add-the-capability-to-offloa.patch | 150 - ...w-QoS-parameter-according-to-the-pac.patch | 94 - ...net-airoha-Implement-LRO-TCP-support.patch | 392 - ...roha-Introduce-airoha_gdm_dev-struct.patch | 1018 --- ...airoha_qdma-pointer-in-airoha_gdm_de.patch | 495 -- ...on-airoha_gdm_dev-pointer-in-airoha_.patch | 73 - ...qos_sq_bmap-in-airoha_gdm_dev-struct.patch | 184 - ...cpu-fwd-_tx_packets-in-airoha_gdm_de.patch | 73 - ...rt-multiple-net_devices-for-a-single.patch | 715 -- ...Do-not-stop-GDM-port-if-it-is-shared.patch | 132 - ...net-airoha-Introduce-WAN-device-flag.patch | 174 - ...rt-multiple-LAN-WAN-interfaces-for-h.patch | 161 - ...e-airoha_set_gdm2_loopback-in-airoha.patch | 37 - ...oha-Add-ethtool-priv_flags-callbacks.patch | 246 - ...-net-airoha-Rework-MTU-configuration.patch | 265 - ...r-handle-MIB-for-GDM-with-multiple-p.patch | 415 - ...-airoha-fix-wrong-airoha_get_fe_port.patch | 40 - 267 files changed, 9 insertions(+), 64283 deletions(-) delete mode 100644 target/linux/airoha/an7581/config-6.12 delete mode 100644 target/linux/airoha/an7583/config-6.12 delete mode 100644 target/linux/airoha/dts/an7581-w1700k-ubi-618.dts delete mode 100644 target/linux/airoha/en7523/config-6.12 delete mode 100644 target/linux/airoha/patches-6.12/016-v6.13-net-airoha-Fix-EGRESS_RATE_METER_EN_MASK-definition.patch delete mode 100644 target/linux/airoha/patches-6.12/029-05-v6.19-spi-airoha-remove-unnecessary-restriction-length.patch delete mode 100644 target/linux/airoha/patches-6.12/029-06-v6.19-spi-airoha-remove-unnecessary-switch-to-non-dma-mode.patch delete mode 100644 target/linux/airoha/patches-6.12/029-07-v6.19-spi-airoha-unify-dirmap-read-write-code.patch delete mode 100644 target/linux/airoha/patches-6.12/029-08-v6.19-spi-airoha-support-of-dualio-quadio-flash-reading-co.patch delete mode 100644 target/linux/airoha/patches-6.12/029-09-v6.19-spi-airoha-avoid-setting-of-page-oob-sizes-in-REG_SP.patch delete mode 100644 target/linux/airoha/patches-6.12/029-10-v6.19-spi-airoha-reduce-the-number-of-modification-of-REG_.patch delete mode 100644 target/linux/airoha/patches-6.12/029-11-v6.19-spi-airoha-set-custom-sector-size-equal-to-flash-pag.patch delete mode 100644 target/linux/airoha/patches-6.12/029-12-v6.19-spi-airoha-avoid-reading-flash-page-settings-from-SN.patch delete mode 100644 target/linux/airoha/patches-6.12/029-13-v6.19-spi-airoha-buffer-must-be-0xff-ed-before-writing.patch delete mode 100644 target/linux/airoha/patches-6.12/029-15-arm-dts-airoha-en7523-add-SNAND-node.patch delete mode 100644 target/linux/airoha/patches-6.12/030-v6.13-hwrng-airoha-add-support-for-Airoha-EN7581-TRNG.patch delete mode 100644 target/linux/airoha/patches-6.12/031-02-v6.13-net-airoha-Simplify-Tx-napi-logic.patch delete mode 100644 target/linux/airoha/patches-6.12/032-v6.13-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch delete mode 100644 target/linux/airoha/patches-6.12/033-05-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch delete mode 100644 target/linux/airoha/patches-6.12/033-06-v6.13-clk-en7523-map-io-region-in-a-single-block.patch delete mode 100644 target/linux/airoha/patches-6.12/034-01-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch delete mode 100644 target/linux/airoha/patches-6.12/034-02-v6.13-pinctrl-airoha-Use-unsigned-long-for-bit-search.patch delete mode 100644 target/linux/airoha/patches-6.12/036-v6.13-net-airoha-Fix-typo-in-REG_CDM2_FWD_CFG-configuratio.patch delete mode 100644 target/linux/airoha/patches-6.12/038-01-v6.14-net-airoha-Enable-Tx-drop-capability-for-each-Tx-DMA.patch delete mode 100644 target/linux/airoha/patches-6.12/038-02-v6.14-net-airoha-Introduce-ndo_select_queue-callback.patch delete mode 100644 target/linux/airoha/patches-6.12/038-03-v6.14-net-airoha-Add-sched-ETS-offload-support.patch delete mode 100644 target/linux/airoha/patches-6.12/038-04-v6.14-net-airoha-Add-sched-HTB-offload-support.patch delete mode 100644 target/linux/airoha/patches-6.12/039-v6.14-cpufreq-airoha-Add-EN7581-CPUFreq-SMCCC-driver.patch delete mode 100644 target/linux/airoha/patches-6.12/039-v6.14-net-airoha-Enforce-ETS-Qdisc-priomap.patch delete mode 100644 target/linux/airoha/patches-6.12/040-v6.14-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch delete mode 100644 target/linux/airoha/patches-6.12/041-01-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch delete mode 100644 target/linux/airoha/patches-6.12/041-02-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch delete mode 100644 target/linux/airoha/patches-6.12/041-03-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch delete mode 100644 target/linux/airoha/patches-6.12/041-04-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch delete mode 100644 target/linux/airoha/patches-6.12/042-01-v6.14-PCI-mediatek-gen3-Rely-on-clk_bulk_prepare_enable-in.patch delete mode 100644 target/linux/airoha/patches-6.12/042-02-v6.14-PCI-mediatek-gen3-Move-reset-assert-callbacks-in-.po.patch delete mode 100644 target/linux/airoha/patches-6.12/042-03-v6.14-PCI-mediatek-gen3-Add-comment-about-initialization-o.patch delete mode 100644 target/linux/airoha/patches-6.12/042-04-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch delete mode 100644 target/linux/airoha/patches-6.12/042-05-v6.14-PCI-mediatek-gen3-Rely-on-msleep-in-mtk_pcie_en7581_.patch delete mode 100644 target/linux/airoha/patches-6.12/042-06-v6.14-PCI-mediatek-gen3-Avoid-PCIe-resetting-via-PERST-for.patch delete mode 100644 target/linux/airoha/patches-6.12/043-v6.15-PCI-mediatek-gen3-Remove-leftover-mac_reset-assert-f.patch delete mode 100644 target/linux/airoha/patches-6.12/044-v6.15-PCI-mediatek-gen3-Configure-PBUS_CSR-registers-for-E.patch delete mode 100644 target/linux/airoha/patches-6.12/046-v6.15-net-airoha-Fix-TSO-support-for-header-cloned-skbs.patch delete mode 100644 target/linux/airoha/patches-6.12/047-v6.13-net-airoha-Reset-BQL-stopping-the-netdevice.patch delete mode 100644 target/linux/airoha/patches-6.12/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch delete mode 100644 target/linux/airoha/patches-6.12/048-02-v6.15-net-airoha-Move-definitions-in-airoha_eth.h.patch delete mode 100644 target/linux/airoha/patches-6.12/048-03-v6.15-net-airoha-Move-reg-write-utility-routines-in-airoha.patch delete mode 100644 target/linux/airoha/patches-6.12/048-04-v6.15-net-airoha-Move-register-definitions-in-airoha_regs..patch delete mode 100644 target/linux/airoha/patches-6.12/048-05-v6.15-net-airoha-Move-DSA-tag-in-DMA-descriptor.patch delete mode 100644 target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch delete mode 100644 target/linux/airoha/patches-6.12/048-07-v6.15-net-airoha-Enable-support-for-multiple-net_devices.patch delete mode 100644 target/linux/airoha/patches-6.12/048-08-v6.15-net-airoha-Move-REG_GDM_FWD_CFG-initialization-in-ai.patch delete mode 100644 target/linux/airoha/patches-6.12/048-09-v6.15-net-airoha-Rename-airoha_set_gdm_port_fwd_cfg-in-air.patch delete mode 100644 target/linux/airoha/patches-6.12/048-12-v6.15-net-airoha-Introduce-Airoha-NPU-support.patch delete mode 100644 target/linux/airoha/patches-6.12/048-13-v6.15-net-airoha-Introduce-flowtable-offload-support.patch delete mode 100644 target/linux/airoha/patches-6.12/048-14-v6.15-net-airoha-Add-loopback-support-for-GDM2.patch delete mode 100644 target/linux/airoha/patches-6.12/048-15-v6.15-net-airoha-Introduce-PPE-debugfs-support.patch delete mode 100644 target/linux/airoha/patches-6.12/049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch delete mode 100644 target/linux/airoha/patches-6.12/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch delete mode 100644 target/linux/airoha/patches-6.12/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch delete mode 100644 target/linux/airoha/patches-6.12/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch delete mode 100644 target/linux/airoha/patches-6.12/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch delete mode 100644 target/linux/airoha/patches-6.12/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch delete mode 100644 target/linux/airoha/patches-6.12/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch delete mode 100644 target/linux/airoha/patches-6.12/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch delete mode 100644 target/linux/airoha/patches-6.12/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch delete mode 100644 target/linux/airoha/patches-6.12/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch delete mode 100644 target/linux/airoha/patches-6.12/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch delete mode 100644 target/linux/airoha/patches-6.12/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch delete mode 100644 target/linux/airoha/patches-6.12/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch delete mode 100644 target/linux/airoha/patches-6.12/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch delete mode 100644 target/linux/airoha/patches-6.12/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch delete mode 100644 target/linux/airoha/patches-6.12/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch delete mode 100644 target/linux/airoha/patches-6.12/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch delete mode 100644 target/linux/airoha/patches-6.12/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch delete mode 100644 target/linux/airoha/patches-6.12/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch delete mode 100644 target/linux/airoha/patches-6.12/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch delete mode 100644 target/linux/airoha/patches-6.12/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch delete mode 100644 target/linux/airoha/patches-6.12/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch delete mode 100644 target/linux/airoha/patches-6.12/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch delete mode 100644 target/linux/airoha/patches-6.12/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch delete mode 100644 target/linux/airoha/patches-6.12/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch delete mode 100644 target/linux/airoha/patches-6.12/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch delete mode 100644 target/linux/airoha/patches-6.12/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch delete mode 100644 target/linux/airoha/patches-6.12/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch delete mode 100644 target/linux/airoha/patches-6.12/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch delete mode 100644 target/linux/airoha/patches-6.12/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch delete mode 100644 target/linux/airoha/patches-6.12/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch delete mode 100644 target/linux/airoha/patches-6.12/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch delete mode 100644 target/linux/airoha/patches-6.12/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch delete mode 100644 target/linux/airoha/patches-6.12/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch delete mode 100644 target/linux/airoha/patches-6.12/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch delete mode 100644 target/linux/airoha/patches-6.12/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch delete mode 100644 target/linux/airoha/patches-6.12/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch delete mode 100644 target/linux/airoha/patches-6.12/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch delete mode 100644 target/linux/airoha/patches-6.12/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch delete mode 100644 target/linux/airoha/patches-6.12/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch delete mode 100644 target/linux/airoha/patches-6.12/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch delete mode 100644 target/linux/airoha/patches-6.12/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch delete mode 100644 target/linux/airoha/patches-6.12/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch delete mode 100644 target/linux/airoha/patches-6.12/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch delete mode 100644 target/linux/airoha/patches-6.12/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch delete mode 100644 target/linux/airoha/patches-6.12/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch delete mode 100644 target/linux/airoha/patches-6.12/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch delete mode 100644 target/linux/airoha/patches-6.12/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch delete mode 100644 target/linux/airoha/patches-6.12/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch delete mode 100644 target/linux/airoha/patches-6.12/088-v6.18-pinctrl-airoha-replace-struct-function_desc-with-str.patch delete mode 100644 target/linux/airoha/patches-6.12/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch delete mode 100644 target/linux/airoha/patches-6.12/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch delete mode 100644 target/linux/airoha/patches-6.12/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch delete mode 100644 target/linux/airoha/patches-6.12/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch delete mode 100644 target/linux/airoha/patches-6.12/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch delete mode 100644 target/linux/airoha/patches-6.12/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch delete mode 100644 target/linux/airoha/patches-6.12/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch delete mode 100644 target/linux/airoha/patches-6.12/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch delete mode 100644 target/linux/airoha/patches-6.12/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch delete mode 100644 target/linux/airoha/patches-6.12/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch delete mode 100644 target/linux/airoha/patches-6.12/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch delete mode 100644 target/linux/airoha/patches-6.12/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch delete mode 100644 target/linux/airoha/patches-6.12/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch delete mode 100644 target/linux/airoha/patches-6.12/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch delete mode 100644 target/linux/airoha/patches-6.12/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch delete mode 100644 target/linux/airoha/patches-6.12/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch delete mode 100644 target/linux/airoha/patches-6.12/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch delete mode 100644 target/linux/airoha/patches-6.12/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch delete mode 100644 target/linux/airoha/patches-6.12/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch delete mode 100644 target/linux/airoha/patches-6.12/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch delete mode 100644 target/linux/airoha/patches-6.12/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch delete mode 100644 target/linux/airoha/patches-6.12/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch delete mode 100644 target/linux/airoha/patches-6.12/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch delete mode 100644 target/linux/airoha/patches-6.12/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch delete mode 100644 target/linux/airoha/patches-6.12/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch delete mode 100644 target/linux/airoha/patches-6.12/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch delete mode 100644 target/linux/airoha/patches-6.12/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch delete mode 100644 target/linux/airoha/patches-6.12/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch delete mode 100644 target/linux/airoha/patches-6.12/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch delete mode 100644 target/linux/airoha/patches-6.12/104-v6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch delete mode 100644 target/linux/airoha/patches-6.12/105-v6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch delete mode 100644 target/linux/airoha/patches-6.12/106-v6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch delete mode 100644 target/linux/airoha/patches-6.12/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch delete mode 100644 target/linux/airoha/patches-6.12/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch delete mode 100644 target/linux/airoha/patches-6.12/109-01-v6.19-pinctrl-airoha-generalize-pins-group-function-confs-.patch delete mode 100644 target/linux/airoha/patches-6.12/109-02-v6.19-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch delete mode 100644 target/linux/airoha/patches-6.12/109-03-v6.19-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch delete mode 100644 target/linux/airoha/patches-6.12/109-05-v6.19-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch delete mode 100644 target/linux/airoha/patches-6.12/110-v6.19-net-airoha-Do-not-loopback-traffic-to-GDM2-if-it-is-.patch delete mode 100644 target/linux/airoha/patches-6.12/111-v6.19-wifi-mt76-Introduce-the-NPU-generic-layer.patch delete mode 100644 target/linux/airoha/patches-6.12/112-v6.19-pinctrl-airoha-fix-pinctrl-function-mismatch-issue.patch delete mode 100644 target/linux/airoha/patches-6.12/113-v6.19-pinctrl-airoha-Fix-AIROHA_PINCTRL_CONFS_DRIVE_E2.patch delete mode 100644 target/linux/airoha/patches-6.12/114-v7.0-hwrng-airoha-set-rng-quality-to-900.patch delete mode 100644 target/linux/airoha/patches-6.12/115-v7.0-net-airoha-Fix-npu-rx-DMA-definitions.patch delete mode 100644 target/linux/airoha/patches-6.12/116-v6.19-net-airoha-Move-net_devs-registration-in-a-dedicated.patch delete mode 100644 target/linux/airoha/patches-6.12/117-v7.0-net-airoha-Use-gdm-port-enum-value-whenever-possible.patch delete mode 100644 target/linux/airoha/patches-6.12/118-v7.0-net-airoha-npu-Dump-fw-version-during-probe.patch delete mode 100644 target/linux/airoha/patches-6.12/119-v6.19-net-airoha-Fix-schedule-while-atomic-in-airoha_ppe_d.patch delete mode 100644 target/linux/airoha/patches-6.12/120-v7.0-net-airoha-implement-get_link_ksettings.patch delete mode 100644 target/linux/airoha/patches-6.12/121-v7.0-net-airoha-npu-Init-BA-memory-region-if-provided-via.patch delete mode 100644 target/linux/airoha/patches-6.12/122-v7.0-net-airoha_eth-increase-max-MTU-to-9220-for-DSA-jumb.patch delete mode 100644 target/linux/airoha/patches-6.12/123-v7.0-net-airoha-npu-Add-the-capability-to-read-firmware-n.patch delete mode 100644 target/linux/airoha/patches-6.12/124-v7.1-net-airoha-fix-typo-in-function-name.patch delete mode 100644 target/linux/airoha/patches-6.12/125-v7.1-net-airoha-Rely-__field_prep-for-non-constant-masks.patch delete mode 100644 target/linux/airoha/patches-6.12/126-v7.1-net-airoha-Make-flow-control-source-port-mapping-dep.patch delete mode 100644 target/linux/airoha/patches-6.12/127-v7.1-net-airoha-Move-GDM-forward-port-configuration-in-nd.patch delete mode 100644 target/linux/airoha/patches-6.12/129-v7.1-net-airoha-select-QDMA-block-according-LAN-WAN-confi.patch delete mode 100644 target/linux/airoha/patches-6.12/130-v7.0-net-airoha-Fix-typo-in-airoha_ppe_setup_tc_block_cb-.patch delete mode 100644 target/linux/airoha/patches-6.12/131-v7.0-net-phy-mediatek-enable-interrupts-on-AN7581.patch delete mode 100644 target/linux/airoha/patches-6.12/132-v7.1-net-airoha-Reset-PPE-default-cput-port-in-airoha_ppe.patch delete mode 100644 target/linux/airoha/patches-6.12/133-v7.1-net-airoha-Rework-the-code-flow-in-airoha_remove-and.patch delete mode 100644 target/linux/airoha/patches-6.12/134-v7.1-net-airoha-Delay-offloading-until-all-net_devices-ar.patch delete mode 100644 target/linux/airoha/patches-6.12/136-v7.1-net-airoha-Add-dma_rmb-and-READ_ONCE-in-airoha_qdma_.patch delete mode 100644 target/linux/airoha/patches-6.12/137-v7.1-net-airoha-Add-missing-PPE-configurations-in-airoha_.patch delete mode 100644 target/linux/airoha/patches-6.12/139-v7.1-net-airoha-Fix-FE_PSE_BUF_SET-configuration-if-PPE2-.patch delete mode 100644 target/linux/airoha/patches-6.12/140-v7.1-net-airoha-Fix-memory-leak-in-airoha_qdma_rx_process.patch delete mode 100644 target/linux/airoha/patches-6.12/141-v7.1-net-airoha-Fix-VIP-configuration-for-AN7583-SoC.patch delete mode 100644 target/linux/airoha/patches-6.12/142-01-v7.1-net-airoha-Rely-on-net_device-pointer-in-airoha_dev_.patch delete mode 100644 target/linux/airoha/patches-6.12/142-02-v7.1-net-airoha-Rely-on-net_device-pointer-in-HTB-callbac.patch delete mode 100644 target/linux/airoha/patches-6.12/142-03-v7.1-net-airoha-Rely-on-net_device-pointer-in-ETS-callbac.patch delete mode 100644 target/linux/airoha/patches-6.12/142-04-v7.1-net-airoha-Remove-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch delete mode 100644 target/linux/airoha/patches-6.12/143-v7.1-net-airoha-Fix-typo-in-airoha_set_gdm2_loopback-rout.patch delete mode 100644 target/linux/airoha/patches-6.12/144-v7.1-net-airoha-Set-REG_RX_CPU_IDX-once-in-airoha_qdma_fi.patch delete mode 100644 target/linux/airoha/patches-6.12/145-01-v7.1-net-airoha-Move-ndesc-initialization-at-end-of-airoh.patch delete mode 100644 target/linux/airoha/patches-6.12/145-02-v7.1-net-airoha-Add-missing-bits-in-airoha_qdma_cleanup_t.patch delete mode 100644 target/linux/airoha/patches-6.12/146-v7.1-net-airoha-Wait-for-NPU-PPE-configuration-to-complet.patch delete mode 100644 target/linux/airoha/patches-6.12/147-v7.1-net-airoha-Fix-PPE-cpu-port-configuration-for-GDM2-l.patch delete mode 100644 target/linux/airoha/patches-6.12/148-v7.1-net-airoha-Fix-possible-TX-queue-stall-in-airoha_qdm.patch delete mode 100644 target/linux/airoha/patches-6.12/150-v7.1-net-airoha-Add-size-check-for-TX-NAPIs-in-airoha_qdm.patch delete mode 100644 target/linux/airoha/patches-6.12/151-v7.1-net-airoha-fix-BQL-imbalance-in-TX-path.patch delete mode 100644 target/linux/airoha/patches-6.12/152-v7.1-net-airoha-stop-net_device-TX-queue-before-updating-.patch delete mode 100644 target/linux/airoha/patches-6.12/153-v7.1-net-airoha-Do-not-wake-all-netdev-TX-queues-in-airoh.patch delete mode 100644 target/linux/airoha/patches-6.12/154-v7.1-net-airoha-Do-not-read-uninitialized-fragment-addres.patch delete mode 100644 target/linux/airoha/patches-6.12/155-v7.2-net-airoha-Rename-get_src_port_id-callback-in-get_sp.patch delete mode 100644 target/linux/airoha/patches-6.12/156-v7.2-net-airoha-Do-not-return-err-in-ndo_stop-callback.patch delete mode 100644 target/linux/airoha/patches-6.12/157-v7.2-net-airoha-Move-entries-to-queue-head-in-case-of-DMA.patch delete mode 100644 target/linux/airoha/patches-6.12/158-v7.2-net-airoha-configure-QoS-channel-for-HW-accelerated-.patch delete mode 100644 target/linux/airoha/patches-6.12/159-v7.2-net-airoha-Introduce-airoha_fe_get-airoha_qdma_get-r.patch delete mode 100644 target/linux/airoha/patches-6.12/160-v7.2-net-airoha-Reserve-RX-headroom-to-avoid-skb-realloca.patch delete mode 100644 target/linux/airoha/patches-6.12/161-v7.2-net-airoha-Disable-GDM2-forwarding-before-configurin.patch delete mode 100644 target/linux/airoha/patches-6.12/200-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch delete mode 100644 target/linux/airoha/patches-6.12/201-crypto-Add-Mediatek-EIP-93-crypto-engine-support.patch delete mode 100644 target/linux/airoha/patches-6.12/202-pinctrl-airoha-permit-GPIO43-46-for-PHY-LED0.patch delete mode 100644 target/linux/airoha/patches-6.12/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch delete mode 100644 target/linux/airoha/patches-6.12/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch delete mode 100644 target/linux/airoha/patches-6.12/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch delete mode 100644 target/linux/airoha/patches-6.12/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch delete mode 100644 target/linux/airoha/patches-6.12/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch delete mode 100644 target/linux/airoha/patches-6.12/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch delete mode 100644 target/linux/airoha/patches-6.12/310-02-net-airoha-deassert-XSI-line-on-hw-init.patch delete mode 100644 target/linux/airoha/patches-6.12/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch delete mode 100644 target/linux/airoha/patches-6.12/310-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch delete mode 100644 target/linux/airoha/patches-6.12/310-07-airoha-ethernet-drop-xsi-mac-reset.patch delete mode 100644 target/linux/airoha/patches-6.12/310-09-net-pcs-airoha-add-PCS-driver-for-Airoha-AN7581-SoC.patch delete mode 100644 target/linux/airoha/patches-6.12/310-10-net-airoha-add-phylink-support-for-GDM2-3-4.patch delete mode 100644 target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch delete mode 100644 target/linux/airoha/patches-6.12/402-01-thermal-airoha-convert-to-regmap-API.patch delete mode 100644 target/linux/airoha/patches-6.12/402-02-thermal-drivers-airoha-Generalize-probe-function.patch delete mode 100644 target/linux/airoha/patches-6.12/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch delete mode 100644 target/linux/airoha/patches-6.12/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch delete mode 100644 target/linux/airoha/patches-6.12/403-v6.18-cpufreq-airoha-Add-support-for-AN7583-SoC.patch delete mode 100644 target/linux/airoha/patches-6.12/600-01-clk-en7523-convert-driver-to-regmap-API.patch delete mode 100644 target/linux/airoha/patches-6.12/600-02-clk-en7523-generalize-register-clocks-function.patch delete mode 100644 target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch delete mode 100644 target/linux/airoha/patches-6.12/600-04-clk-en7523-add-support-for-.set_rate.patch delete mode 100644 target/linux/airoha/patches-6.12/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch delete mode 100644 target/linux/airoha/patches-6.12/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch delete mode 100644 target/linux/airoha/patches-6.12/600-08-clk-en7523-add-support-for-probing-SCU-child.patch delete mode 100644 target/linux/airoha/patches-6.12/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch delete mode 100644 target/linux/airoha/patches-6.12/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch delete mode 100644 target/linux/airoha/patches-6.12/600-11-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch delete mode 100644 target/linux/airoha/patches-6.12/600-12-clk-en7523-Add-reset-controller-support-for-EN7523-S.patch delete mode 100644 target/linux/airoha/patches-6.12/600-13-ARM-dts-airoha-update-EN7523-dtsi-to-support-resets.patch delete mode 100644 target/linux/airoha/patches-6.12/604-01-net-pcs-airoha-add-support-for-AN7583.patch delete mode 100644 target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch delete mode 100644 target/linux/airoha/patches-6.12/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch delete mode 100644 target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch delete mode 100644 target/linux/airoha/patches-6.12/801-01-net-phy-add-PHY_DETACH_NO_HW_RESET-PHY-flag.patch delete mode 100644 target/linux/airoha/patches-6.12/801-02-net-phy-as21xxx-add-flag-PHY_DETACH_NO_HW_RESET.patch delete mode 100644 target/linux/airoha/patches-6.12/802-01-net-phy-as21xxx-handle-corner-case-with-link-and-aut.patch delete mode 100644 target/linux/airoha/patches-6.12/802-02-net-phy-as21xxx-fix-read_status-speed-handling.patch delete mode 100644 target/linux/airoha/patches-6.12/802-03-net-phy-as21xxx-force-C45-OPs-for-AUTONEG.patch delete mode 100644 target/linux/airoha/patches-6.12/804-net-phy-as21xxx-implement-read-workaround-for-C45-re.patch delete mode 100644 target/linux/airoha/patches-6.12/885-i2c-mt7621-optional-reset.patch delete mode 100644 target/linux/airoha/patches-6.12/886-uart-add-en7523-support.patch delete mode 100644 target/linux/airoha/patches-6.12/900-airoha-bmt-support.patch delete mode 100644 target/linux/airoha/patches-6.12/901-snand-mtk-bmt-support.patch delete mode 100644 target/linux/airoha/patches-6.12/911-clk-en7581-Separate-PERST-from-refclk-in-PCIe-clock.patch delete mode 100644 target/linux/airoha/patches-6.12/912-pcie-mediatek-gen3-Add-x2-link-support-for-Airoha-EN7581.patch delete mode 100644 target/linux/airoha/patches-6.12/915-01-net-netfilter-flowtable-Add-the-capability-to-offloa.patch delete mode 100644 target/linux/airoha/patches-6.12/915-02-net-airoha-Set-hw-QoS-parameter-according-to-the-pac.patch delete mode 100644 target/linux/airoha/patches-6.12/916-net-airoha-Implement-LRO-TCP-support.patch delete mode 100644 target/linux/airoha/patches-6.12/920-01-net-airoha-Introduce-airoha_gdm_dev-struct.patch delete mode 100644 target/linux/airoha/patches-6.12/920-02-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch delete mode 100644 target/linux/airoha/patches-6.12/920-03-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch delete mode 100644 target/linux/airoha/patches-6.12/920-04-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch delete mode 100644 target/linux/airoha/patches-6.12/920-05-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch delete mode 100644 target/linux/airoha/patches-6.12/920-06-net-airoha-Support-multiple-net_devices-for-a-single.patch delete mode 100644 target/linux/airoha/patches-6.12/920-07-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch delete mode 100644 target/linux/airoha/patches-6.12/920-08-net-airoha-Introduce-WAN-device-flag.patch delete mode 100644 target/linux/airoha/patches-6.12/920-09-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch delete mode 100644 target/linux/airoha/patches-6.12/920-10-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch delete mode 100644 target/linux/airoha/patches-6.12/920-12-net-airoha-Add-ethtool-priv_flags-callbacks.patch delete mode 100644 target/linux/airoha/patches-6.12/920-13-net-airoha-Rework-MTU-configuration.patch delete mode 100644 target/linux/airoha/patches-6.12/920-14-net-airoha-Better-handle-MIB-for-GDM-with-multiple-p.patch delete mode 100644 target/linux/airoha/patches-6.12/920-15-net-airoha-fix-wrong-airoha_get_fe_port.patch diff --git a/target/linux/airoha/Makefile b/target/linux/airoha/Makefile index cf3629ef205..9c4c1c39a97 100644 --- a/target/linux/airoha/Makefile +++ b/target/linux/airoha/Makefile @@ -6,8 +6,7 @@ BOARDNAME:=Airoha ARM SUBTARGETS:=en7523 an7581 an7583 FEATURES:=dt squashfs nand ramdisk gpio -KERNEL_PATCHVER:=6.12 -KERNEL_TESTING_PATCHVER:=6.18 +KERNEL_PATCHVER:=6.18 include $(INCLUDE_DIR)/target.mk DEFAULT_PACKAGES += \ diff --git a/target/linux/airoha/an7581/base-files/etc/init.d/airoha_fan b/target/linux/airoha/an7581/base-files/etc/init.d/airoha_fan index ab9eeca83ae..d30205f546b 100755 --- a/target/linux/airoha/an7581/base-files/etc/init.d/airoha_fan +++ b/target/linux/airoha/an7581/base-files/etc/init.d/airoha_fan @@ -15,7 +15,7 @@ find_nct7802() return fi done - echo "/sys/class/hwmon/hwmon3" # fallback + echo "/sys/class/hwmon/hwmon5" # fallback } boot() diff --git a/target/linux/airoha/an7581/config-6.12 b/target/linux/airoha/an7581/config-6.12 deleted file mode 100644 index 3acef03fb45..00000000000 --- a/target/linux/airoha/an7581/config-6.12 +++ /dev/null @@ -1,387 +0,0 @@ -CONFIG_64BIT=y -CONFIG_AIROHA_CPU_PM_DOMAIN=y -CONFIG_AIROHA_SCU_SSR=y -CONFIG_AIROHA_THERMAL=y -CONFIG_AIROHA_WATCHDOG=y -CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y -CONFIG_ARCH_AIROHA=y -CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y -CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y -CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_FORCE_MAX_ORDER=10 -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_PKEY_BITS=3 -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_STACKWALK=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_WANTS_EXECMEM_LATE=y -CONFIG_ARCH_WANTS_NO_INSTR=y -CONFIG_ARCH_WANTS_THP_SWAP=y -CONFIG_ARM64=y -CONFIG_ARM64_4K_PAGES=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y -CONFIG_ARM64_PA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -CONFIG_ARM64_PLATFORM_DEVICES=y -CONFIG_ARM64_TAGGED_ADDR_ABI=y -CONFIG_ARM64_VA_BITS=39 -CONFIG_ARM64_VA_BITS_39=y -CONFIG_ARM_AIROHA_SOC_CPUFREQ=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V2M=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_PMU=y -CONFIG_ARM_PMUV3=y -CONFIG_ARM_PSCI_FW=y -CONFIG_ARM_SMCCC_SOC_ID=y -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_PM=y -CONFIG_BLOCK_NOTIFIERS=y -CONFIG_BUFFER_HEAD=y -CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y -CONFIG_CC_HAVE_SHADOW_CALL_STACK=y -CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_EN7523=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -# CONFIG_COMPAT_32BIT_TIME is not set -CONFIG_CONTEXT_TRACKING=y -CONFIG_CONTEXT_TRACKING_IDLE=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_MITIGATIONS=y -CONFIG_CPU_RMAP=y -CONFIG_CRC16=y -CONFIG_CRC_CCITT=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_GF128MUL=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_MISC=y -CONFIG_DEV_COREDUMP=y -CONFIG_DMADEVICES=y -CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y -CONFIG_DMA_DIRECT_REMAP=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_NEED_SYNC=y -CONFIG_DMA_OF=y -CONFIG_DTC=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_EXT4_FS=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FRAME_POINTER=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FUNCTION_ALIGNMENT=4 -CONFIG_FUNCTION_ALIGNMENT_4B=y -CONFIG_FWNODE_MDIO=y -# CONFIG_FW_LOADER_USER_HELPER is not set -CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_DEVICES=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IOREMAP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GLOB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_EN7523=y -CONFIG_GPIO_GENERIC=y -CONFIG_GRO_CELLS=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HOTPLUG_CORE_SYNC=y -CONFIG_HOTPLUG_CORE_SYNC_DEAD=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_AIROHA=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IO_URING=y -CONFIG_IPV6=y -CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -CONFIG_IP_MROUTE=y -CONFIG_IP_MROUTE_COMMON=y -# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MSI_LIB=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LRU_GEN_WALKS_MMU=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -# CONFIG_MDIO_AIROHA is not set -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MEDIATEK_GE_SOC_PHY=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_CQHCI=y -CONFIG_MMC_MTK=y -CONFIG_MMU_LAZY_TLB_REFCOUNT=y -CONFIG_MODULES_TREE_LOOKUP=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_MTK_BMT=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_SPI_NAND=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_FIT_FW=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -CONFIG_MTD_UBI_NVMEM=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTK_NET_PHYLIB=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_AIROHA=y -# CONFIG_NET_AIROHA_FLOW_STATS is not set -CONFIG_NET_AIROHA_NPU=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MT7530=y -# CONFIG_NET_DSA_MT7530_MDIO is not set -CONFIG_NET_DSA_MT7530_MMIO=y -CONFIG_NET_DSA_TAG_MTK=y -CONFIG_NET_EGRESS=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_INGRESS=y -CONFIG_NET_SELFTESTS=y -# CONFIG_NET_VENDOR_3COM is not set -CONFIG_NET_VENDOR_AIROHA=y -# CONFIG_NET_VENDOR_MEDIATEK is not set -CONFIG_NET_XGRESS=y -CONFIG_NLS=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=4 -CONFIG_NVMEM=y -CONFIG_NVMEM_BLOCK=y -CONFIG_NVMEM_LAYOUTS=y -CONFIG_NVMEM_LAYOUT_ASCII_ENV=y -CONFIG_NVMEM_SYSFS=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_PADATA=y -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PARTITION_PERCPU=y -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEFAULT is not set -CONFIG_PCIEASPM_PERFORMANCE=y -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_MEDIATEK=y -CONFIG_PCIE_MEDIATEK_GEN3=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -CONFIG_PCS_AIROHA=y -CONFIG_PCS_AIROHA_AN7581=y -# CONFIG_PCS_AIROHA_AN7583 is not set -CONFIG_PERF_EVENTS=y -CONFIG_PER_VMA_LOCK=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYLIB_LEDS=y -CONFIG_PHYLINK=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PHY_AIROHA_PCIE=y -CONFIG_PHY_AIROHA_USB=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_AIROHA=y -# CONFIG_PINCTRL_MT2712 is not set -# CONFIG_PINCTRL_MT6765 is not set -# CONFIG_PINCTRL_MT6795 is not set -# CONFIG_PINCTRL_MT6797 is not set -# CONFIG_PINCTRL_MT7622 is not set -# CONFIG_PINCTRL_MT7981 is not set -# CONFIG_PINCTRL_MT7986 is not set -# CONFIG_PINCTRL_MT8173 is not set -# CONFIG_PINCTRL_MT8183 is not set -# CONFIG_PINCTRL_MT8186 is not set -# CONFIG_PINCTRL_MT8188 is not set -# CONFIG_PINCTRL_MT8516 is not set -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_OPP=y -CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_SUPPLY=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RELOCATABLE=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RODATA_FULL_DEFAULT_ENABLED=y -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SERIAL_8250_AIROHA=y -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=5 -CONFIG_SERIAL_8250_RUNTIME_UARTS=5 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SGL_ALLOC=y -CONFIG_SMP=y -CONFIG_SND=y -CONFIG_SND_SOC=y -CONFIG_SND_SOC_AN7581=y -CONFIG_SND_SOC_AN7581_WM8960=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SOC_BUS=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SOUND=y -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_AIROHA_EN7523 is not set -CONFIG_SPI_AIROHA_SNFI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPLIT_PMD_PTLOCKS=y -CONFIG_SPLIT_PTE_PTLOCKS=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TOOLS_SUPPORT_RELR=y -CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -CONFIG_UIMAGE_FIT_BLK=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set -CONFIG_USB_SUPPORT=y -CONFIG_USER_STACKTRACE_SUPPORT=y -CONFIG_VDSO_GETRANDOM=y -CONFIG_VMAP_STACK=y -CONFIG_WANT_DEV_COREDUMP=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WLAN is not set -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZONE_DMA32=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/airoha/an7583/config-6.12 b/target/linux/airoha/an7583/config-6.12 deleted file mode 100644 index 392603a41f9..00000000000 --- a/target/linux/airoha/an7583/config-6.12 +++ /dev/null @@ -1,375 +0,0 @@ -CONFIG_64BIT=y -CONFIG_AIROHA_CPU_PM_DOMAIN=y -CONFIG_AIROHA_SCU_SSR=y -CONFIG_AIROHA_THERMAL=y -CONFIG_AIROHA_WATCHDOG=y -CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y -CONFIG_ARCH_AIROHA=y -CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y -CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y -CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_FORCE_MAX_ORDER=10 -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_STACKWALK=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_WANTS_NO_INSTR=y -CONFIG_ARCH_WANTS_THP_SWAP=y -CONFIG_ARM64=y -CONFIG_ARM64_4K_PAGES=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y -CONFIG_ARM64_PA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -CONFIG_ARM64_PLATFORM_DEVICES=y -CONFIG_ARM64_TAGGED_ADDR_ABI=y -CONFIG_ARM64_VA_BITS=39 -CONFIG_ARM64_VA_BITS_39=y -# CONFIG_ARM64_VA_BITS_48 is not set -# CONFIG_ARM64_VA_BITS_52 is not set -CONFIG_ARM_AIROHA_SOC_CPUFREQ=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -# CONFIG_ARM_DEBUG_WX is not set -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V2M=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_PMU=y -CONFIG_ARM_PMUV3=y -CONFIG_ARM_PSCI_FW=y -CONFIG_ARM_SMCCC_SOC_ID=y -# CONFIG_ARM_SMMU is not set -# CONFIG_ARM_SMMU_V3 is not set -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_PM=y -CONFIG_BUFFER_HEAD=y -CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y -CONFIG_CC_HAVE_SHADOW_CALL_STACK=y -CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_EN7523=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -# CONFIG_COMPAT_32BIT_TIME is not set -# CONFIG_COMPRESSED_INSTALL is not set -CONFIG_CONTEXT_TRACKING=y -CONFIG_CONTEXT_TRACKING_IDLE=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_RMAP=y -CONFIG_CRC16=y -CONFIG_CRC_CCITT=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DEV_EIP93=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_GF128MUL=y -CONFIG_CRYPTO_LIB_SHA256=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_MISC=y -CONFIG_DMADEVICES=y -CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y -CONFIG_DMA_DIRECT_REMAP=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_NEED_SYNC=y -CONFIG_DMA_OF=y -CONFIG_DMA_OPS_HELPERS=y -CONFIG_DTC=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EXT4_FS=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FRAME_POINTER=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FUNCTION_ALIGNMENT=4 -CONFIG_FUNCTION_ALIGNMENT_4B=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_CACHE=y -# CONFIG_FW_LOADER_USER_HELPER is not set -CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_DEVICES=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IOREMAP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GLOB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_EN7523=y -CONFIG_GPIO_GENERIC=y -CONFIG_GRO_CELLS=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_IOPORT_MAP=y -# CONFIG_HISILICON_ERRATUM_162100801 is not set -CONFIG_HOTPLUG_CORE_SYNC=y -CONFIG_HOTPLUG_CORE_SYNC_DEAD=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_AIROHA=y -# CONFIG_IDPF is not set -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_IO_URING=y -CONFIG_IPC_NS=y -CONFIG_IPV6=y -CONFIG_IPV6_MULTIPLE_TABLES=y -# CONFIG_IPV6_SUBTREES is not set -CONFIG_IP_MROUTE=y -CONFIG_IP_MROUTE_COMMON=y -# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MSI_LIB=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LRU_GEN_WALKS_MMU=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MDIO_AIROHA=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -# CONFIG_MEDIATEK_GE_SOC_PHY is not set -# CONFIG_MEMCG is not set -CONFIG_MFD_SYSCON=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_CQHCI=y -CONFIG_MMC_MTK=y -CONFIG_MMU_LAZY_TLB_REFCOUNT=y -CONFIG_MODULES_TREE_LOOKUP=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_MTK_BMT=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_SPI_NAND=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_FIT_FW=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_AIROHA=y -# CONFIG_NET_AIROHA_FLOW_STATS is not set -CONFIG_NET_AIROHA_NPU=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MT7530=y -CONFIG_NET_DSA_MT7530_MDIO=y -CONFIG_NET_DSA_MT7530_MMIO=y -CONFIG_NET_DSA_TAG_MTK=y -CONFIG_NET_FLOW_LIMIT=y -# CONFIG_NET_MEDIATEK_SOC is not set -CONFIG_NET_SELFTESTS=y -# CONFIG_NET_VENDOR_3COM is not set -CONFIG_NET_VENDOR_AIROHA=y -# CONFIG_NET_VENDOR_MEDIATEK is not set -CONFIG_NLS=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=4 -CONFIG_NVMEM=y -CONFIG_NVMEM_BLOCK=y -CONFIG_NVMEM_LAYOUTS=y -CONFIG_NVMEM_LAYOUT_ASCII_ENV=y -CONFIG_NVMEM_SYSFS=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PARTITION_PERCPU=y -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEFAULT is not set -CONFIG_PCIEASPM_PERFORMANCE=y -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_MEDIATEK=y -CONFIG_PCIE_MEDIATEK_GEN3=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -# CONFIG_PCS_AIROHA_AN7581 is not set -CONFIG_PCS_AIROHA_AN7583=y -CONFIG_PERF_EVENTS=y -CONFIG_PER_VMA_LOCK=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYLIB_LEDS=y -CONFIG_PHYLINK=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PHY_AIROHA_PCIE=y -# CONFIG_PHY_AIROHA_USB is not set -CONFIG_PINCTRL=y -CONFIG_PINCTRL_AIROHA=y -# CONFIG_PINCTRL_MT2712 is not set -# CONFIG_PINCTRL_MT6765 is not set -# CONFIG_PINCTRL_MT6795 is not set -# CONFIG_PINCTRL_MT6797 is not set -# CONFIG_PINCTRL_MT7622 is not set -# CONFIG_PINCTRL_MT7981 is not set -# CONFIG_PINCTRL_MT7986 is not set -# CONFIG_PINCTRL_MT8173 is not set -# CONFIG_PINCTRL_MT8183 is not set -# CONFIG_PINCTRL_MT8186 is not set -# CONFIG_PINCTRL_MT8188 is not set -# CONFIG_PINCTRL_MT8516 is not set -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_OPP=y -CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_SUPPLY=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RELOCATABLE=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RODATA_FULL_DEFAULT_ENABLED=y -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SERIAL_8250_AIROHA=y -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=5 -CONFIG_SERIAL_8250_RUNTIME_UARTS=5 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SGL_ALLOC=y -CONFIG_SMP=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SOC_BUS=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_AIROHA_EN7523 is not set -CONFIG_SPI_AIROHA_SNFI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -# CONFIG_TEST_FPU is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -# CONFIG_UNMAP_KERNEL_AT_EL0 is not set -CONFIG_USER_STACKTRACE_SUPPORT=y -CONFIG_VDSO_GETRANDOM=y -CONFIG_VMAP_STACK=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WLAN is not set -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZONE_DMA32=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/airoha/dts/an7581-w1700k-ubi-618.dts b/target/linux/airoha/dts/an7581-w1700k-ubi-618.dts deleted file mode 100644 index 100eb36bb03..00000000000 --- a/target/linux/airoha/dts/an7581-w1700k-ubi-618.dts +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT - -/dts-v1/; - -#include "an7581-w1700k-ubi.dts" - -&phy5 { - tx-polarity = ; - rx-polarity = ; -}; - -&phy8 { - tx-polarity = ; - rx-polarity = ; -}; diff --git a/target/linux/airoha/dts/an7581-w1700k-ubi.dts b/target/linux/airoha/dts/an7581-w1700k-ubi.dts index de9900f75a8..4aa281c79d6 100644 --- a/target/linux/airoha/dts/an7581-w1700k-ubi.dts +++ b/target/linux/airoha/dts/an7581-w1700k-ubi.dts @@ -366,8 +366,8 @@ reset-deassert-us = <200000>; // interrupt-parent = <&en7581_pinctrl>; // interrupts = <22 IRQ_TYPE_LEVEL_LOW>; - realtek,pnswap-tx; - realtek,pnswap-rx; + tx-polarity = ; + rx-polarity = ; }; phy8: ethernet-phy@8 { @@ -378,8 +378,8 @@ reset-deassert-us = <200000>; // interrupt-parent = <&en7581_pinctrl>; // interrupts = <23 IRQ_TYPE_LEVEL_LOW>; - realtek,pnswap-tx; - realtek,pnswap-rx; + tx-polarity = ; + rx-polarity = ; }; }; }; diff --git a/target/linux/airoha/en7523/config-6.12 b/target/linux/airoha/en7523/config-6.12 deleted file mode 100644 index 825b2cc5362..00000000000 --- a/target/linux/airoha/en7523/config-6.12 +++ /dev/null @@ -1,313 +0,0 @@ -CONFIG_AIROHA_CPU_PM_DOMAIN=y -CONFIG_AIROHA_WATCHDOG=y -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_AIROHA=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_STACKWALK=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_GIC_V3_ITS_PCI=y -CONFIG_ARM_HAS_GROUP_RELOCS=y -CONFIG_ARM_HEAVY_MB=y -# CONFIG_ARM_HIGHBANK_CPUIDLE is not set -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_PSCI=y -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_SMMU is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_ATAGS=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_PM=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_CACHE_L2X0=y -CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMDLINE="rootfstype=squashfs,jffs2" -CONFIG_CMDLINE_FROM_BOOTLOADER=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_EN7523=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONTEXT_TRACKING=y -CONFIG_CONTEXT_TRACKING_IDLE=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_MITIGATIONS=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SPECTRE=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_GF128MUL=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_CURRENT_POINTER_IN_TPIDRURO=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -CONFIG_DEBUG_MISC=y -CONFIG_DMA_OPS=y -CONFIG_DTC=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FS_IOMAP=y -CONFIG_FUNCTION_ALIGNMENT=0 -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_VDSO_32=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_EN7523=y -CONFIG_GPIO_GENERIC=y -# CONFIG_HARDEN_BRANCH_HISTORY is not set -# CONFIG_HARDEN_BRANCH_PREDICTOR is not set -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_SMP=y -CONFIG_HOTPLUG_CORE_SYNC=y -CONFIG_HOTPLUG_CORE_SYNC_DEAD=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_AIROHA=y -CONFIG_HZ_FIXED=0 -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_IOMMUFD is not set -# CONFIG_IOMMU_DEBUGFS is not set -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set -CONFIG_IOMMU_SUPPORT=y -CONFIG_IRQCHIP=y -CONFIG_IRQSTACKS=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_TIME_ACCOUNTING=y -CONFIG_IRQ_WORK=y -# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -# CONFIG_MDIO_AIROHA is not set -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGRATION=y -CONFIG_MMU_LAZY_TLB_REFCOUNT=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_ECC_SW_HAMMING=y -CONFIG_MTD_SPI_NAND=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_FIT_FW=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SRCU_NMI_SAFE=y -CONFIG_NET_AIROHA=y -# CONFIG_NET_AIROHA_FLOW_STATS is not set -CONFIG_NET_AIROHA_NPU=y -CONFIG_NET_EGRESS=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_INGRESS=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_VENDOR_AIROHA=y -# CONFIG_NET_VENDOR_MEDIATEK is not set -CONFIG_NET_XGRESS=y -CONFIG_NLS=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=2 -CONFIG_NVMEM=y -CONFIG_NVMEM_LAYOUTS=y -CONFIG_NVMEM_SYSFS=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PARTITION_PERCPU=y -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_MEDIATEK=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -# CONFIG_PCS_AIROHA_AN7581 is not set -# CONFIG_PCS_AIROHA_AN7583 is not set -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLIB_LEDS=y -CONFIG_PHY_AIROHA_PCIE=y -CONFIG_PINCTRL=y -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PREEMPT_NONE_BUILD=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PWM=y -# CONFIG_PWM_AIROHA is not set -CONFIG_PWM_SYSFS=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -CONFIG_SERIAL_8250_AIROHA=y -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -# CONFIG_SERIAL_8250_SHARE_IRQ is not set -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_AIROHA_EN7523=y -CONFIG_SPI_AIROHA_SNFI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_STACKTRACE=y -# CONFIG_SWAP is not set -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNWINDER_ARM=y -CONFIG_USB=y -CONFIG_USB_COMMON=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_XHCI_HCD=y -# CONFIG_USB_XHCI_PLATFORM is not set -CONFIG_USE_OF=y -# CONFIG_VFP is not set -CONFIG_WATCHDOG_CORE=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/airoha/image/an7581.mk b/target/linux/airoha/image/an7581.mk index 0beed840b6d..7323eba0da0 100644 --- a/target/linux/airoha/image/an7581.mk +++ b/target/linux/airoha/image/an7581.mk @@ -96,27 +96,14 @@ define Device/gemtek_w1700k-ubi DEVICE_ALT2_VENDOR := Quantum Fiber DEVICE_ALT2_MODEL := W1700K DEVICE_ALT2_VARIANT := UBI - ifeq ($(KERNEL_PATCHVER),6.18) - DEVICE_DTS := an7581-w1700k-ubi-618 - else - DEVICE_DTS := an7581-w1700k-ubi - endif + DEVICE_DTS := an7581-w1700k-ubi DEVICE_COMPAT_VERSION := 2.0 DEVICE_COMPAT_MESSAGE := Partition table has been changed to cooperate \ with the vendor bootloader with regard to the BMT/BBT partition at \ the end of flash. A reinstall including corrected chainloader is needed. DEVICE_PACKAGES := airoha-en7581-mt7996-npu-firmware fitblk kmod-i2c-an7581 \ - kmod-hwmon-nct7802 kmod-mt7996-firmware wpad-basic-mbedtls - ifeq ($(DUMP),1) - # HACK adds: both packages to build the config dependency tree - DEVICE_PACKAGES += rtl8261n-firmware kmod-phy-rtl8261n - else - ifeq ($(KERNEL_PATCHVER),6.18) - DEVICE_PACKAGES += rtl8261n-firmware - else - DEVICE_PACKAGES += kmod-phy-rtl8261n - endif - endif + kmod-hwmon-nct7802 kmod-mt7996-firmware wpad-basic-mbedtls \ + rtl8261n-firmware UBINIZE_OPTS := -E 5 BLOCKSIZE := 128k PAGESIZE := 2048 diff --git a/target/linux/airoha/patches-6.12/016-v6.13-net-airoha-Fix-EGRESS_RATE_METER_EN_MASK-definition.patch b/target/linux/airoha/patches-6.12/016-v6.13-net-airoha-Fix-EGRESS_RATE_METER_EN_MASK-definition.patch deleted file mode 100644 index d70cadf9d99..00000000000 --- a/target/linux/airoha/patches-6.12/016-v6.13-net-airoha-Fix-EGRESS_RATE_METER_EN_MASK-definition.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 2518b119639162251b6cc7195aec394930c1d867 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 9 Oct 2024 00:21:47 +0200 -Subject: [PATCH] net: airoha: Fix EGRESS_RATE_METER_EN_MASK definition - -Fix typo in EGRESS_RATE_METER_EN_MASK mask definition. This bus in not -introducing any user visible problem since, even if we are setting -EGRESS_RATE_METER_EN_MASK bit in REG_EGRESS_RATE_METER_CFG register, -egress QoS metering is not supported yet since we are missing some other -hw configurations (e.g token bucket rate, token bucket size). - -Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet support -for EN7581 SoC") - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20241009-airoha-fixes-v2-1-18af63ec19bf@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -554,7 +554,7 @@ - #define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) - - #define REG_EGRESS_RATE_METER_CFG 0x100c --#define EGRESS_RATE_METER_EN_MASK BIT(29) -+#define EGRESS_RATE_METER_EN_MASK BIT(31) - #define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) - #define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) - #define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) diff --git a/target/linux/airoha/patches-6.12/029-05-v6.19-spi-airoha-remove-unnecessary-restriction-length.patch b/target/linux/airoha/patches-6.12/029-05-v6.19-spi-airoha-remove-unnecessary-restriction-length.patch deleted file mode 100644 index c99c25921c7..00000000000 --- a/target/linux/airoha/patches-6.12/029-05-v6.19-spi-airoha-remove-unnecessary-restriction-length.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 661856ca131c8bf6724905966e02149805660abe Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:16:53 +0300 -Subject: [PATCH 05/14] spi: airoha: remove unnecessary restriction length - -The "length < 160" restriction is not needed because airoha_snand_write_data() -and airoha_snand_read_data() will properly handle data transfers above -SPI_MAX_TRANSFER_SIZE. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno -Link: https://patch.msgid.link/20251012121707.2296160-3-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -619,13 +619,6 @@ static int airoha_snand_adjust_op_size(s - - if (op->data.nbytes > max_len) - op->data.nbytes = max_len; -- } else { -- max_len = 1 + op->addr.nbytes + op->dummy.nbytes; -- if (max_len >= 160) -- return -EOPNOTSUPP; -- -- if (op->data.nbytes > 160 - max_len) -- op->data.nbytes = 160 - max_len; - } - - return 0; diff --git a/target/linux/airoha/patches-6.12/029-06-v6.19-spi-airoha-remove-unnecessary-switch-to-non-dma-mode.patch b/target/linux/airoha/patches-6.12/029-06-v6.19-spi-airoha-remove-unnecessary-switch-to-non-dma-mode.patch deleted file mode 100644 index afe496c968f..00000000000 --- a/target/linux/airoha/patches-6.12/029-06-v6.19-spi-airoha-remove-unnecessary-switch-to-non-dma-mode.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7350f8dc15bfbb7abf1ce4babea6fcace1c574c5 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:16:55 +0300 -Subject: [PATCH 06/14] spi: airoha: remove unnecessary switch to non-dma mode - -The code switches to dma at the start of dirmap operation and returns -to non-dma at the end of dirmap operation, so an additional switch to -non-dma at the start of dirmap write is not required. - -Signed-off-by: Mikhail Kshevetskiy -Acked-by: Lorenzo Bianconi -Reviewed-by: AngeloGioacchino Del Regno -Link: https://patch.msgid.link/20251012121707.2296160-5-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -815,9 +815,6 @@ static ssize_t airoha_snand_dirmap_write - int err; - - as_ctrl = spi_controller_get_devdata(spi->controller); -- err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); -- if (err < 0) -- return err; - - memcpy(txrx_buf + offs, buf, len); - dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, diff --git a/target/linux/airoha/patches-6.12/029-07-v6.19-spi-airoha-unify-dirmap-read-write-code.patch b/target/linux/airoha/patches-6.12/029-07-v6.19-spi-airoha-unify-dirmap-read-write-code.patch deleted file mode 100644 index c85c6861fc2..00000000000 --- a/target/linux/airoha/patches-6.12/029-07-v6.19-spi-airoha-unify-dirmap-read-write-code.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 233a22687411ea053a4b169c07324ee6aa33bf38 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:16:58 +0300 -Subject: [PATCH 07/14] spi: airoha: unify dirmap read/write code - -Makes dirmap writing looks similar to dirmap reading. Just a minor -refactoring, no behavior change is expected. - -Signed-off-by: Mikhail Kshevetskiy -Link: https://patch.msgid.link/20251012121707.2296160-8-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 50 ++++++++++++++++++++++------------- - 1 file changed, 32 insertions(+), 18 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -672,6 +672,8 @@ static ssize_t airoha_snand_dirmap_read( - u32 val, rd_mode; - int err; - -+ as_ctrl = spi_controller_get_devdata(spi->controller); -+ - switch (op->cmd.opcode) { - case SPI_NAND_OP_READ_FROM_CACHE_DUAL: - rd_mode = 1; -@@ -684,7 +686,6 @@ static ssize_t airoha_snand_dirmap_read( - break; - } - -- as_ctrl = spi_controller_get_devdata(spi->controller); - err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); - if (err < 0) - return err; -@@ -748,7 +749,7 @@ static ssize_t airoha_snand_dirmap_read( - if (err) - goto error_dma_unmap; - -- /* trigger dma start read */ -+ /* trigger dma reading */ - err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, - SPI_NFI_RD_TRIG); - if (err) -@@ -806,37 +807,47 @@ error_dma_mode_off: - static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, - u64 offs, size_t len, const void *buf) - { -- struct spi_mem_op *op = &desc->info.op_tmpl; - struct spi_device *spi = desc->mem->spi; - u8 *txrx_buf = spi_get_ctldata(spi); - struct airoha_snand_ctrl *as_ctrl; - dma_addr_t dma_addr; -- u32 wr_mode, val; -+ u32 wr_mode, val, opcode; - int err; - - as_ctrl = spi_controller_get_devdata(spi->controller); - -+ opcode = desc->info.op_tmpl.cmd.opcode; -+ switch (opcode) { -+ case SPI_NAND_OP_PROGRAM_LOAD_SINGLE: -+ case SPI_NAND_OP_PROGRAM_LOAD_RAMDOM_SINGLE: -+ wr_mode = 0; -+ break; -+ case SPI_NAND_OP_PROGRAM_LOAD_QUAD: -+ case SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD: -+ wr_mode = 2; -+ break; -+ default: -+ /* unknown opcode */ -+ return -EOPNOTSUPP; -+ } -+ - memcpy(txrx_buf + offs, buf, len); -- dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, -- DMA_TO_DEVICE); -- err = dma_mapping_error(as_ctrl->dev, dma_addr); -- if (err) -- return err; - - err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); - if (err < 0) -- goto error_dma_unmap; -+ return err; - - err = airoha_snand_nfi_config(as_ctrl); - if (err) -- goto error_dma_unmap; -+ goto error_dma_mode_off; - -- if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD || -- op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD) -- wr_mode = BIT(1); -- else -- wr_mode = 0; -+ dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, -+ DMA_TO_DEVICE); -+ err = dma_mapping_error(as_ctrl->dev, dma_addr); -+ if (err) -+ goto error_dma_mode_off; - -+ /* set dma addr */ - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, - dma_addr); - if (err) -@@ -850,12 +861,13 @@ static ssize_t airoha_snand_dirmap_write - if (err) - goto error_dma_unmap; - -+ /* set write command */ - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1, -- FIELD_PREP(SPI_NFI_PG_LOAD_CMD, -- op->cmd.opcode)); -+ FIELD_PREP(SPI_NFI_PG_LOAD_CMD, opcode)); - if (err) - goto error_dma_unmap; - -+ /* set write mode */ - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, - FIELD_PREP(SPI_NFI_DATA_READ_WR_MODE, wr_mode)); - if (err) -@@ -887,6 +899,7 @@ static ssize_t airoha_snand_dirmap_write - if (err) - goto error_dma_unmap; - -+ /* trigger dma writing */ - err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, - SPI_NFI_WR_TRIG); - if (err) -@@ -931,6 +944,7 @@ static ssize_t airoha_snand_dirmap_write - error_dma_unmap: - dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, - DMA_TO_DEVICE); -+error_dma_mode_off: - airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); - return err; - } diff --git a/target/linux/airoha/patches-6.12/029-08-v6.19-spi-airoha-support-of-dualio-quadio-flash-reading-co.patch b/target/linux/airoha/patches-6.12/029-08-v6.19-spi-airoha-support-of-dualio-quadio-flash-reading-co.patch deleted file mode 100644 index 7e3fcb47647..00000000000 --- a/target/linux/airoha/patches-6.12/029-08-v6.19-spi-airoha-support-of-dualio-quadio-flash-reading-co.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 80b09137aeab27e59004383058f8cc696a9ee048 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:16:59 +0300 -Subject: [PATCH 08/14] spi: airoha: support of dualio/quadio flash reading - commands - -Airoha snfi spi controller supports acceleration of DUAL/QUAD -operations, but does not supports DUAL_IO/QUAD_IO operations. -Luckily DUAL/QUAD operations do the same as DUAL_IO/QUAD_IO ones, -so we can issue corresponding DUAL/QUAD operation instead of -DUAL_IO/QUAD_IO one. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno -Link: https://patch.msgid.link/20251012121707.2296160-9-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 28 ++++++++++++++++++++++------ - 1 file changed, 22 insertions(+), 6 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -147,6 +147,8 @@ - #define SPI_NFI_CUS_SEC_SIZE_EN BIT(16) - - #define REG_SPI_NFI_RD_CTL2 0x0510 -+#define SPI_NFI_DATA_READ_CMD GENMASK(7, 0) -+ - #define REG_SPI_NFI_RD_CTL3 0x0514 - - #define REG_SPI_NFI_PG_CTL1 0x0524 -@@ -179,7 +181,9 @@ - #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE 0x03 - #define SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST 0x0b - #define SPI_NAND_OP_READ_FROM_CACHE_DUAL 0x3b -+#define SPI_NAND_OP_READ_FROM_CACHE_DUALIO 0xbb - #define SPI_NAND_OP_READ_FROM_CACHE_QUAD 0x6b -+#define SPI_NAND_OP_READ_FROM_CACHE_QUADIO 0xeb - #define SPI_NAND_OP_WRITE_ENABLE 0x06 - #define SPI_NAND_OP_WRITE_DISABLE 0x04 - #define SPI_NAND_OP_PROGRAM_LOAD_SINGLE 0x02 -@@ -664,26 +668,38 @@ static int airoha_snand_dirmap_create(st - static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, - u64 offs, size_t len, void *buf) - { -- struct spi_mem_op *op = &desc->info.op_tmpl; - struct spi_device *spi = desc->mem->spi; - struct airoha_snand_ctrl *as_ctrl; - u8 *txrx_buf = spi_get_ctldata(spi); - dma_addr_t dma_addr; -- u32 val, rd_mode; -+ u32 val, rd_mode, opcode; - int err; - - as_ctrl = spi_controller_get_devdata(spi->controller); - -- switch (op->cmd.opcode) { -+ /* -+ * DUALIO and QUADIO opcodes are not supported by the spi controller, -+ * replace them with supported opcodes. -+ */ -+ opcode = desc->info.op_tmpl.cmd.opcode; -+ switch (opcode) { -+ case SPI_NAND_OP_READ_FROM_CACHE_SINGLE: -+ case SPI_NAND_OP_READ_FROM_CACHE_SINGLE_FAST: -+ rd_mode = 0; -+ break; - case SPI_NAND_OP_READ_FROM_CACHE_DUAL: -+ case SPI_NAND_OP_READ_FROM_CACHE_DUALIO: -+ opcode = SPI_NAND_OP_READ_FROM_CACHE_DUAL; - rd_mode = 1; - break; - case SPI_NAND_OP_READ_FROM_CACHE_QUAD: -+ case SPI_NAND_OP_READ_FROM_CACHE_QUADIO: -+ opcode = SPI_NAND_OP_READ_FROM_CACHE_QUAD; - rd_mode = 2; - break; - default: -- rd_mode = 0; -- break; -+ /* unknown opcode */ -+ return -EOPNOTSUPP; - } - - err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); -@@ -717,7 +733,7 @@ static ssize_t airoha_snand_dirmap_read( - - /* set read command */ - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2, -- op->cmd.opcode); -+ FIELD_PREP(SPI_NFI_DATA_READ_CMD, opcode)); - if (err) - goto error_dma_unmap; - diff --git a/target/linux/airoha/patches-6.12/029-09-v6.19-spi-airoha-avoid-setting-of-page-oob-sizes-in-REG_SP.patch b/target/linux/airoha/patches-6.12/029-09-v6.19-spi-airoha-avoid-setting-of-page-oob-sizes-in-REG_SP.patch deleted file mode 100644 index f8902f7e575..00000000000 --- a/target/linux/airoha/patches-6.12/029-09-v6.19-spi-airoha-avoid-setting-of-page-oob-sizes-in-REG_SP.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 70eec454f2d6cdfab547c262781acd38328e11a1 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:17:00 +0300 -Subject: [PATCH 09/14] spi: airoha: avoid setting of page/oob sizes in - REG_SPI_NFI_PAGEFMT - -spi-airoha-snfi uses custom sector size in REG_SPI_NFI_SECCUS_SIZE -register, so setting of page/oob sizes in REG_SPI_NFI_PAGEFMT is not -required. - -Signed-off-by: Mikhail Kshevetskiy -Link: https://patch.msgid.link/20251012121707.2296160-10-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 38 ----------------------------------- - 1 file changed, 38 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -518,44 +518,6 @@ static int airoha_snand_nfi_config(struc - if (err) - return err; - -- /* page format */ -- switch (as_ctrl->nfi_cfg.spare_size) { -- case 26: -- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x1); -- break; -- case 27: -- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x2); -- break; -- case 28: -- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x3); -- break; -- default: -- val = FIELD_PREP(SPI_NFI_SPARE_SIZE, 0x0); -- break; -- } -- -- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT, -- SPI_NFI_SPARE_SIZE, val); -- if (err) -- return err; -- -- switch (as_ctrl->nfi_cfg.page_size) { -- case 2048: -- val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x1); -- break; -- case 4096: -- val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x2); -- break; -- default: -- val = FIELD_PREP(SPI_NFI_PAGE_SIZE, 0x0); -- break; -- } -- -- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT, -- SPI_NFI_PAGE_SIZE, val); -- if (err) -- return err; -- - /* sec num */ - val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, diff --git a/target/linux/airoha/patches-6.12/029-10-v6.19-spi-airoha-reduce-the-number-of-modification-of-REG_.patch b/target/linux/airoha/patches-6.12/029-10-v6.19-spi-airoha-reduce-the-number-of-modification-of-REG_.patch deleted file mode 100644 index 40e2f6ea218..00000000000 --- a/target/linux/airoha/patches-6.12/029-10-v6.19-spi-airoha-reduce-the-number-of-modification-of-REG_.patch +++ /dev/null @@ -1,199 +0,0 @@ -From d1ff30df1d9a4eb4c067795abb5e2a66910fd108 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:17:01 +0300 -Subject: [PATCH 10/14] spi: airoha: reduce the number of modification of - REG_SPI_NFI_CNFG and REG_SPI_NFI_SECCUS_SIZE registers - -This just reduce the number of modification of REG_SPI_NFI_CNFG and -REG_SPI_NFI_SECCUS_SIZE registers during dirmap operation. - -This patch is a necessary step to avoid reading flash page settings -from SNFI registers during driver startup. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno -Link: https://patch.msgid.link/20251012121707.2296160-11-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 135 +++++++++++++++++++++++++--------- - 1 file changed, 102 insertions(+), 33 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -668,7 +668,48 @@ static ssize_t airoha_snand_dirmap_read( - if (err < 0) - return err; - -- err = airoha_snand_nfi_config(as_ctrl); -+ /* NFI reset */ -+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -+ SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); -+ if (err) -+ goto error_dma_mode_off; -+ -+ /* NFI configure: -+ * - No AutoFDM (custom sector size (SECCUS) register will be used) -+ * - No SoC's hardware ECC (flash internal ECC will be used) -+ * - Use burst mode (faster, but requires 16 byte alignment for addresses) -+ * - Setup for reading (SPI_NFI_READ_MODE) -+ * - Setup reading command: FIELD_PREP(SPI_NFI_OPMODE, 6) -+ * - Use DMA instead of PIO for data reading -+ */ -+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -+ SPI_NFI_DMA_MODE | -+ SPI_NFI_READ_MODE | -+ SPI_NFI_DMA_BURST_EN | -+ SPI_NFI_HW_ECC_EN | -+ SPI_NFI_AUTO_FDM_EN | -+ SPI_NFI_OPMODE, -+ SPI_NFI_DMA_MODE | -+ SPI_NFI_READ_MODE | -+ SPI_NFI_DMA_BURST_EN | -+ FIELD_PREP(SPI_NFI_OPMODE, 6)); -+ if (err) -+ goto error_dma_mode_off; -+ -+ /* Set number of sector will be read */ -+ val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); -+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -+ SPI_NFI_SEC_NUM, val); -+ if (err) -+ goto error_dma_mode_off; -+ -+ /* Set custom sector size */ -+ val = as_ctrl->nfi_cfg.sec_size; -+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, -+ SPI_NFI_CUS_SEC_SIZE | -+ SPI_NFI_CUS_SEC_SIZE_EN, -+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) | -+ SPI_NFI_CUS_SEC_SIZE_EN); - if (err) - goto error_dma_mode_off; - -@@ -684,7 +725,14 @@ static ssize_t airoha_snand_dirmap_read( - if (err) - goto error_dma_unmap; - -- /* set cust sec size */ -+ /* -+ * Setup transfer length -+ * --------------------- -+ * The following rule MUST be met: -+ * transfer_length = -+ * = NFI_SNF_MISC_CTL2.read_data_byte_number = -+ * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size -+ */ - val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num; - val = FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, val); - err = regmap_update_bits(as_ctrl->regmap_nfi, -@@ -711,18 +759,6 @@ static ssize_t airoha_snand_dirmap_read( - if (err) - goto error_dma_unmap; - -- /* set nfi read */ -- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_OPMODE, -- FIELD_PREP(SPI_NFI_OPMODE, 6)); -- if (err) -- goto error_dma_unmap; -- -- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_READ_MODE | SPI_NFI_DMA_MODE); -- if (err) -- goto error_dma_unmap; -- - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0); - if (err) - goto error_dma_unmap; -@@ -815,7 +851,48 @@ static ssize_t airoha_snand_dirmap_write - if (err < 0) - return err; - -- err = airoha_snand_nfi_config(as_ctrl); -+ /* NFI reset */ -+ err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -+ SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); -+ if (err) -+ goto error_dma_mode_off; -+ -+ /* -+ * NFI configure: -+ * - No AutoFDM (custom sector size (SECCUS) register will be used) -+ * - No SoC's hardware ECC (flash internal ECC will be used) -+ * - Use burst mode (faster, but requires 16 byte alignment for addresses) -+ * - Setup for writing (SPI_NFI_READ_MODE bit is cleared) -+ * - Setup writing command: FIELD_PREP(SPI_NFI_OPMODE, 3) -+ * - Use DMA instead of PIO for data writing -+ */ -+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -+ SPI_NFI_DMA_MODE | -+ SPI_NFI_READ_MODE | -+ SPI_NFI_DMA_BURST_EN | -+ SPI_NFI_HW_ECC_EN | -+ SPI_NFI_AUTO_FDM_EN | -+ SPI_NFI_OPMODE, -+ SPI_NFI_DMA_MODE | -+ SPI_NFI_DMA_BURST_EN | -+ FIELD_PREP(SPI_NFI_OPMODE, 3)); -+ if (err) -+ goto error_dma_mode_off; -+ -+ /* Set number of sector will be written */ -+ val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); -+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -+ SPI_NFI_SEC_NUM, val); -+ if (err) -+ goto error_dma_mode_off; -+ -+ /* Set custom sector size */ -+ val = as_ctrl->nfi_cfg.sec_size; -+ err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, -+ SPI_NFI_CUS_SEC_SIZE | -+ SPI_NFI_CUS_SEC_SIZE_EN, -+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) | -+ SPI_NFI_CUS_SEC_SIZE_EN); - if (err) - goto error_dma_mode_off; - -@@ -831,8 +908,16 @@ static ssize_t airoha_snand_dirmap_write - if (err) - goto error_dma_unmap; - -- val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, -- as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num); -+ /* -+ * Setup transfer length -+ * --------------------- -+ * The following rule MUST be met: -+ * transfer_length = -+ * = NFI_SNF_MISC_CTL2.write_data_byte_number = -+ * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size -+ */ -+ val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num; -+ val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, val); - err = regmap_update_bits(as_ctrl->regmap_nfi, - REG_SPI_NFI_SNF_MISC_CTL2, - SPI_NFI_PROG_LOAD_BYTE_NUM, val); -@@ -857,22 +942,6 @@ static ssize_t airoha_snand_dirmap_write - if (err) - goto error_dma_unmap; - -- err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_READ_MODE); -- if (err) -- goto error_dma_unmap; -- -- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_OPMODE, -- FIELD_PREP(SPI_NFI_OPMODE, 3)); -- if (err) -- goto error_dma_unmap; -- -- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_DMA_MODE); -- if (err) -- goto error_dma_unmap; -- - err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80); - if (err) - goto error_dma_unmap; diff --git a/target/linux/airoha/patches-6.12/029-11-v6.19-spi-airoha-set-custom-sector-size-equal-to-flash-pag.patch b/target/linux/airoha/patches-6.12/029-11-v6.19-spi-airoha-set-custom-sector-size-equal-to-flash-pag.patch deleted file mode 100644 index 514212835ce..00000000000 --- a/target/linux/airoha/patches-6.12/029-11-v6.19-spi-airoha-set-custom-sector-size-equal-to-flash-pag.patch +++ /dev/null @@ -1,142 +0,0 @@ -From fb81b5cecb8553e3ca2b45288cf340d43c9c2991 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:17:02 +0300 -Subject: [PATCH 11/14] spi: airoha: set custom sector size equal to flash page - size - -Set custom sector size equal to flash page size including oob. Thus we -will always read a single sector. The maximum custom sector size is -8187, so all possible flash sector sizes are supported. - -This patch is a necessary step to avoid reading flash page settings -from SNFI registers during driver startup. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno -Link: https://patch.msgid.link/20251012121707.2296160-12-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 35 +++++++++++++++++++---------------- - 1 file changed, 19 insertions(+), 16 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -519,7 +519,7 @@ static int airoha_snand_nfi_config(struc - return err; - - /* sec num */ -- val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); -+ val = FIELD_PREP(SPI_NFI_SEC_NUM, 1); - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, - SPI_NFI_SEC_NUM, val); - if (err) -@@ -532,7 +532,8 @@ static int airoha_snand_nfi_config(struc - return err; - - /* set cust sec size */ -- val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, as_ctrl->nfi_cfg.sec_size); -+ val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, -+ as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num); - return regmap_update_bits(as_ctrl->regmap_nfi, - REG_SPI_NFI_SECCUS_SIZE, - SPI_NFI_CUS_SEC_SIZE, val); -@@ -635,10 +636,13 @@ static ssize_t airoha_snand_dirmap_read( - u8 *txrx_buf = spi_get_ctldata(spi); - dma_addr_t dma_addr; - u32 val, rd_mode, opcode; -+ size_t bytes; - int err; - - as_ctrl = spi_controller_get_devdata(spi->controller); - -+ bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size; -+ - /* - * DUALIO and QUADIO opcodes are not supported by the spi controller, - * replace them with supported opcodes. -@@ -697,18 +701,17 @@ static ssize_t airoha_snand_dirmap_read( - goto error_dma_mode_off; - - /* Set number of sector will be read */ -- val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -- SPI_NFI_SEC_NUM, val); -+ SPI_NFI_SEC_NUM, -+ FIELD_PREP(SPI_NFI_SEC_NUM, 1)); - if (err) - goto error_dma_mode_off; - - /* Set custom sector size */ -- val = as_ctrl->nfi_cfg.sec_size; - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, - SPI_NFI_CUS_SEC_SIZE | - SPI_NFI_CUS_SEC_SIZE_EN, -- FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) | -+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) | - SPI_NFI_CUS_SEC_SIZE_EN); - if (err) - goto error_dma_mode_off; -@@ -733,11 +736,10 @@ static ssize_t airoha_snand_dirmap_read( - * = NFI_SNF_MISC_CTL2.read_data_byte_number = - * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size - */ -- val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num; -- val = FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, val); - err = regmap_update_bits(as_ctrl->regmap_nfi, - REG_SPI_NFI_SNF_MISC_CTL2, -- SPI_NFI_READ_DATA_BYTE_NUM, val); -+ SPI_NFI_READ_DATA_BYTE_NUM, -+ FIELD_PREP(SPI_NFI_READ_DATA_BYTE_NUM, bytes)); - if (err) - goto error_dma_unmap; - -@@ -826,10 +828,13 @@ static ssize_t airoha_snand_dirmap_write - struct airoha_snand_ctrl *as_ctrl; - dma_addr_t dma_addr; - u32 wr_mode, val, opcode; -+ size_t bytes; - int err; - - as_ctrl = spi_controller_get_devdata(spi->controller); - -+ bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size; -+ - opcode = desc->info.op_tmpl.cmd.opcode; - switch (opcode) { - case SPI_NAND_OP_PROGRAM_LOAD_SINGLE: -@@ -880,18 +885,17 @@ static ssize_t airoha_snand_dirmap_write - goto error_dma_mode_off; - - /* Set number of sector will be written */ -- val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -- SPI_NFI_SEC_NUM, val); -+ SPI_NFI_SEC_NUM, -+ FIELD_PREP(SPI_NFI_SEC_NUM, 1)); - if (err) - goto error_dma_mode_off; - - /* Set custom sector size */ -- val = as_ctrl->nfi_cfg.sec_size; - err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, - SPI_NFI_CUS_SEC_SIZE | - SPI_NFI_CUS_SEC_SIZE_EN, -- FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, val) | -+ FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, bytes) | - SPI_NFI_CUS_SEC_SIZE_EN); - if (err) - goto error_dma_mode_off; -@@ -916,11 +920,10 @@ static ssize_t airoha_snand_dirmap_write - * = NFI_SNF_MISC_CTL2.write_data_byte_number = - * = NFI_CON.sector_number * NFI_SECCUS.custom_sector_size - */ -- val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num; -- val = FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, val); - err = regmap_update_bits(as_ctrl->regmap_nfi, - REG_SPI_NFI_SNF_MISC_CTL2, -- SPI_NFI_PROG_LOAD_BYTE_NUM, val); -+ SPI_NFI_PROG_LOAD_BYTE_NUM, -+ FIELD_PREP(SPI_NFI_PROG_LOAD_BYTE_NUM, bytes)); - if (err) - goto error_dma_unmap; - diff --git a/target/linux/airoha/patches-6.12/029-12-v6.19-spi-airoha-avoid-reading-flash-page-settings-from-SN.patch b/target/linux/airoha/patches-6.12/029-12-v6.19-spi-airoha-avoid-reading-flash-page-settings-from-SN.patch deleted file mode 100644 index 00fd100bc36..00000000000 --- a/target/linux/airoha/patches-6.12/029-12-v6.19-spi-airoha-avoid-reading-flash-page-settings-from-SN.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 902c0ea18a97b1a6eeee5799cb1fd9a79ef9208e Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:17:03 +0300 -Subject: [PATCH 12/14] spi: airoha: avoid reading flash page settings from - SNFI registers during driver startup - -The spinand driver do 3 type of dirmap requests: - * read/write whole flash page without oob - (offs = 0, len = page_size) - * read/write whole flash page including oob - (offs = 0, len = page_size + oob_size) - * read/write oob area only - (offs = page_size, len = oob_size) - -The trick is: - * read/write a single "sector" - * set a custom sector size equal to offs + len. It's a bit safer to - rounded up "sector size" value 64. - * set the transfer length equal to custom sector size - -And it works! - -Thus we can remove a dirty hack that reads flash page settings from -SNFI registers during driver startup. Also airoha_snand_adjust_op_size() -function becomes unnecessary. - -Signed-off-by: Mikhail Kshevetskiy -Link: https://patch.msgid.link/20251012121707.2296160-13-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 115 ++-------------------------------- - 1 file changed, 5 insertions(+), 110 deletions(-) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -223,13 +223,6 @@ struct airoha_snand_ctrl { - struct regmap *regmap_ctrl; - struct regmap *regmap_nfi; - struct clk *spi_clk; -- -- struct { -- size_t page_size; -- size_t sec_size; -- u8 sec_num; -- u8 spare_size; -- } nfi_cfg; - }; - - static int airoha_snand_set_fifo_op(struct airoha_snand_ctrl *as_ctrl, -@@ -490,55 +483,6 @@ static int airoha_snand_nfi_init(struct - SPI_NFI_ALL_IRQ_EN, SPI_NFI_AHB_DONE_EN); - } - --static int airoha_snand_nfi_config(struct airoha_snand_ctrl *as_ctrl) --{ -- int err; -- u32 val; -- -- err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -- SPI_NFI_FIFO_FLUSH | SPI_NFI_RST); -- if (err) -- return err; -- -- /* auto FDM */ -- err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_AUTO_FDM_EN); -- if (err) -- return err; -- -- /* HW ECC */ -- err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_HW_ECC_EN); -- if (err) -- return err; -- -- /* DMA Burst */ -- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, -- SPI_NFI_DMA_BURST_EN); -- if (err) -- return err; -- -- /* sec num */ -- val = FIELD_PREP(SPI_NFI_SEC_NUM, 1); -- err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, -- SPI_NFI_SEC_NUM, val); -- if (err) -- return err; -- -- /* enable cust sec size */ -- err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, -- SPI_NFI_CUS_SEC_SIZE_EN); -- if (err) -- return err; -- -- /* set cust sec size */ -- val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, -- as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num); -- return regmap_update_bits(as_ctrl->regmap_nfi, -- REG_SPI_NFI_SECCUS_SIZE, -- SPI_NFI_CUS_SEC_SIZE, val); --} -- - static bool airoha_snand_is_page_ops(const struct spi_mem_op *op) - { - if (op->addr.nbytes != 2) -@@ -571,26 +515,6 @@ static bool airoha_snand_is_page_ops(con - } - } - --static int airoha_snand_adjust_op_size(struct spi_mem *mem, -- struct spi_mem_op *op) --{ -- size_t max_len; -- -- if (airoha_snand_is_page_ops(op)) { -- struct airoha_snand_ctrl *as_ctrl; -- -- as_ctrl = spi_controller_get_devdata(mem->spi->controller); -- max_len = as_ctrl->nfi_cfg.sec_size; -- max_len += as_ctrl->nfi_cfg.spare_size; -- max_len *= as_ctrl->nfi_cfg.sec_num; -- -- if (op->data.nbytes > max_len) -- op->data.nbytes = max_len; -- } -- -- return 0; --} -- - static bool airoha_snand_supports_op(struct spi_mem *mem, - const struct spi_mem_op *op) - { -@@ -641,7 +565,8 @@ static ssize_t airoha_snand_dirmap_read( - - as_ctrl = spi_controller_get_devdata(spi->controller); - -- bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size; -+ /* minimum oob size is 64 */ -+ bytes = round_up(offs + len, 64); - - /* - * DUALIO and QUADIO opcodes are not supported by the spi controller, -@@ -833,7 +758,8 @@ static ssize_t airoha_snand_dirmap_write - - as_ctrl = spi_controller_get_devdata(spi->controller); - -- bytes = as_ctrl->nfi_cfg.sec_num * as_ctrl->nfi_cfg.sec_size; -+ /* minimum oob size is 64 */ -+ bytes = round_up(offs + len, 64); - - opcode = desc->info.op_tmpl.cmd.opcode; - switch (opcode) { -@@ -1076,7 +1002,6 @@ static int airoha_snand_exec_op(struct s - } - - static const struct spi_controller_mem_ops airoha_snand_mem_ops = { -- .adjust_op_size = airoha_snand_adjust_op_size, - .supports_op = airoha_snand_supports_op, - .exec_op = airoha_snand_exec_op, - .dirmap_create = airoha_snand_dirmap_create, -@@ -1106,36 +1031,6 @@ static int airoha_snand_setup(struct spi - return 0; - } - --static int airoha_snand_nfi_setup(struct airoha_snand_ctrl *as_ctrl) --{ -- u32 val, sec_size, sec_num; -- int err; -- -- err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, &val); -- if (err) -- return err; -- -- sec_num = FIELD_GET(SPI_NFI_SEC_NUM, val); -- -- err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, &val); -- if (err) -- return err; -- -- sec_size = FIELD_GET(SPI_NFI_CUS_SEC_SIZE, val); -- -- /* init default value */ -- as_ctrl->nfi_cfg.sec_size = sec_size; -- as_ctrl->nfi_cfg.sec_num = sec_num; -- as_ctrl->nfi_cfg.page_size = round_down(sec_size * sec_num, 1024); -- as_ctrl->nfi_cfg.spare_size = 16; -- -- err = airoha_snand_nfi_init(as_ctrl); -- if (err) -- return err; -- -- return airoha_snand_nfi_config(as_ctrl); --} -- - static const struct regmap_config spi_ctrl_regmap_config = { - .name = "ctrl", - .reg_bits = 32, -@@ -1227,7 +1122,7 @@ static int airoha_snand_probe(struct pla - ctrl->setup = airoha_snand_setup; - device_set_node(&ctrl->dev, dev_fwnode(dev)); - -- err = airoha_snand_nfi_setup(as_ctrl); -+ err = airoha_snand_nfi_init(as_ctrl); - if (err) - return err; - diff --git a/target/linux/airoha/patches-6.12/029-13-v6.19-spi-airoha-buffer-must-be-0xff-ed-before-writing.patch b/target/linux/airoha/patches-6.12/029-13-v6.19-spi-airoha-buffer-must-be-0xff-ed-before-writing.patch deleted file mode 100644 index 669f9b2dd43..00000000000 --- a/target/linux/airoha/patches-6.12/029-13-v6.19-spi-airoha-buffer-must-be-0xff-ed-before-writing.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0743acf746a81e0460a56fd5ff847d97fa7eb370 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sun, 12 Oct 2025 15:17:04 +0300 -Subject: [PATCH 13/14] spi: airoha: buffer must be 0xff-ed before writing - -During writing, the entire flash page (including OOB) will be updated -with the values from the temporary buffer, so we need to fill the -untouched areas of the buffer with 0xff value to prevent accidental -data overwriting. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno -Link: https://patch.msgid.link/20251012121707.2296160-14-mikhail.kshevetskiy@iopsys.eu -Signed-off-by: Mark Brown ---- - drivers/spi/spi-airoha-snfi.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/spi/spi-airoha-snfi.c -+++ b/drivers/spi/spi-airoha-snfi.c -@@ -776,7 +776,11 @@ static ssize_t airoha_snand_dirmap_write - return -EOPNOTSUPP; - } - -+ if (offs > 0) -+ memset(txrx_buf, 0xff, offs); - memcpy(txrx_buf + offs, buf, len); -+ if (bytes > offs + len) -+ memset(txrx_buf + offs + len, 0xff, bytes - offs - len); - - err = airoha_snand_set_mode(as_ctrl, SPI_MODE_DMA); - if (err < 0) diff --git a/target/linux/airoha/patches-6.12/029-15-arm-dts-airoha-en7523-add-SNAND-node.patch b/target/linux/airoha/patches-6.12/029-15-arm-dts-airoha-en7523-add-SNAND-node.patch deleted file mode 100644 index bd68440b309..00000000000 --- a/target/linux/airoha/patches-6.12/029-15-arm-dts-airoha-en7523-add-SNAND-node.patch +++ /dev/null @@ -1,40 +0,0 @@ -From bb2f9b3d71717c7df942deb1488c56e544d4a32c Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Fri, 10 Oct 2025 06:01:33 +0300 -Subject: [PATCH v6 3/3] arm: dts: airoha: en7523: add SNAND node - -Add SNAND node to enable support of attached SPI-NAND on the EN7523 SoC. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno ---- - arch/arm/boot/dts/airoha/en7523.dtsi | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/arch/arm/boot/dts/airoha/en7523.dtsi -+++ b/arch/arm/boot/dts/airoha/en7523.dtsi -@@ -203,4 +203,24 @@ - #interrupt-cells = <1>; - }; - }; -+ -+ spi_ctrl: spi@1fa10000 { -+ compatible = "airoha,en7523-snand", "airoha,en7581-snand"; -+ reg = <0x1fa10000 0x140>, -+ <0x1fa11000 0x160>; -+ -+ clocks = <&scu EN7523_CLK_SPI>; -+ clock-names = "spi"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ nand: nand@0 { -+ compatible = "spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <50000000>; -+ spi-tx-bus-width = <1>; -+ spi-rx-bus-width = <2>; -+ }; -+ }; - }; diff --git a/target/linux/airoha/patches-6.12/030-v6.13-hwrng-airoha-add-support-for-Airoha-EN7581-TRNG.patch b/target/linux/airoha/patches-6.12/030-v6.13-hwrng-airoha-add-support-for-Airoha-EN7581-TRNG.patch deleted file mode 100644 index e21fb5649e2..00000000000 --- a/target/linux/airoha/patches-6.12/030-v6.13-hwrng-airoha-add-support-for-Airoha-EN7581-TRNG.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 5c5db81bff81a0fcd9ad998543d4241cbfe4742f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 17 Oct 2024 14:44:38 +0200 -Subject: [PATCH 2/2] hwrng: airoha - add support for Airoha EN7581 TRNG - -Add support for Airoha TRNG. The Airoha SoC provide a True RNG module -that can output 4 bytes of raw data at times. - -The module makes use of various noise source to provide True Random -Number Generation. - -On probe the module is reset to operate Health Test and verify correct -execution of it. - -The module can also provide DRBG function but the execution mode is -mutually exclusive, running as TRNG doesn't permit to also run it as -DRBG. - -Signed-off-by: Christian Marangi -Reviewed-by: Martin Kaiser -Signed-off-by: Herbert Xu ---- - drivers/char/hw_random/Kconfig | 13 ++ - drivers/char/hw_random/Makefile | 1 + - drivers/char/hw_random/airoha-trng.c | 243 +++++++++++++++++++++++++++ - 3 files changed, 257 insertions(+) - create mode 100644 drivers/char/hw_random/airoha-trng.c - ---- a/drivers/char/hw_random/Kconfig -+++ b/drivers/char/hw_random/Kconfig -@@ -62,6 +62,19 @@ config HW_RANDOM_AMD - - If unsure, say Y. - -+config HW_RANDOM_AIROHA -+ tristate "Airoha True HW Random Number Generator support" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ default HW_RANDOM -+ help -+ This driver provides kernel-side support for the True Random Number -+ Generator hardware found on Airoha SoC. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called airoha-rng. -+ -+ If unsure, say Y. -+ - config HW_RANDOM_ATMEL - tristate "Atmel Random Number Generator support" - depends on (ARCH_AT91 || COMPILE_TEST) ---- a/drivers/char/hw_random/Makefile -+++ b/drivers/char/hw_random/Makefile -@@ -8,6 +8,7 @@ rng-core-y := core.o - obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o - obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o - obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o -+obj-$(CONFIG_HW_RANDOM_AIROHA) += airoha-trng.o - obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o - obj-$(CONFIG_HW_RANDOM_BA431) += ba431-rng.o - obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o ---- /dev/null -+++ b/drivers/char/hw_random/airoha-trng.c -@@ -0,0 +1,243 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Copyright (C) 2024 Christian Marangi */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TRNG_IP_RDY 0x800 -+#define CNT_TRANS GENMASK(15, 8) -+#define SAMPLE_RDY BIT(0) -+#define TRNG_NS_SEK_AND_DAT_EN 0x804 -+#define RNG_EN BIT(31) /* referenced as ring_en */ -+#define RAW_DATA_EN BIT(16) -+#define TRNG_HEALTH_TEST_SW_RST 0x808 -+#define SW_RST BIT(0) /* Active High */ -+#define TRNG_INTR_EN 0x818 -+#define INTR_MASK BIT(16) -+#define CONTINUOUS_HEALTH_INITR_EN BIT(2) -+#define SW_STARTUP_INITR_EN BIT(1) -+#define RST_STARTUP_INITR_EN BIT(0) -+/* Notice that Health Test are done only out of Reset and with RNG_EN */ -+#define TRNG_HEALTH_TEST_STATUS 0x824 -+#define CONTINUOUS_HEALTH_AP_TEST_FAIL BIT(23) -+#define CONTINUOUS_HEALTH_RC_TEST_FAIL BIT(22) -+#define SW_STARTUP_TEST_DONE BIT(21) -+#define SW_STARTUP_AP_TEST_FAIL BIT(20) -+#define SW_STARTUP_RC_TEST_FAIL BIT(19) -+#define RST_STARTUP_TEST_DONE BIT(18) -+#define RST_STARTUP_AP_TEST_FAIL BIT(17) -+#define RST_STARTUP_RC_TEST_FAIL BIT(16) -+#define RAW_DATA_VALID BIT(7) -+ -+#define TRNG_RAW_DATA_OUT 0x828 -+ -+#define TRNG_CNT_TRANS_VALID 0x80 -+#define BUSY_LOOP_SLEEP 10 -+#define BUSY_LOOP_TIMEOUT (BUSY_LOOP_SLEEP * 10000) -+ -+struct airoha_trng { -+ void __iomem *base; -+ struct hwrng rng; -+ struct device *dev; -+ -+ struct completion rng_op_done; -+}; -+ -+static int airoha_trng_irq_mask(struct airoha_trng *trng) -+{ -+ u32 val; -+ -+ val = readl(trng->base + TRNG_INTR_EN); -+ val |= INTR_MASK; -+ writel(val, trng->base + TRNG_INTR_EN); -+ -+ return 0; -+} -+ -+static int airoha_trng_irq_unmask(struct airoha_trng *trng) -+{ -+ u32 val; -+ -+ val = readl(trng->base + TRNG_INTR_EN); -+ val &= ~INTR_MASK; -+ writel(val, trng->base + TRNG_INTR_EN); -+ -+ return 0; -+} -+ -+static int airoha_trng_init(struct hwrng *rng) -+{ -+ struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng); -+ int ret; -+ u32 val; -+ -+ val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN); -+ val |= RNG_EN; -+ writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN); -+ -+ /* Set out of SW Reset */ -+ airoha_trng_irq_unmask(trng); -+ writel(0, trng->base + TRNG_HEALTH_TEST_SW_RST); -+ -+ ret = wait_for_completion_timeout(&trng->rng_op_done, BUSY_LOOP_TIMEOUT); -+ if (ret <= 0) { -+ dev_err(trng->dev, "Timeout waiting for Health Check\n"); -+ airoha_trng_irq_mask(trng); -+ return -ENODEV; -+ } -+ -+ /* Check if Health Test Failed */ -+ val = readl(trng->base + TRNG_HEALTH_TEST_STATUS); -+ if (val & (RST_STARTUP_AP_TEST_FAIL | RST_STARTUP_RC_TEST_FAIL)) { -+ dev_err(trng->dev, "Health Check fail: %s test fail\n", -+ val & RST_STARTUP_AP_TEST_FAIL ? "AP" : "RC"); -+ return -ENODEV; -+ } -+ -+ /* Check if IP is ready */ -+ ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val, -+ val & SAMPLE_RDY, 10, 1000); -+ if (ret < 0) { -+ dev_err(trng->dev, "Timeout waiting for IP ready"); -+ return -ENODEV; -+ } -+ -+ /* CNT_TRANS must be 0x80 for IP to be considered ready */ -+ ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val, -+ FIELD_GET(CNT_TRANS, val) == TRNG_CNT_TRANS_VALID, -+ 10, 1000); -+ if (ret < 0) { -+ dev_err(trng->dev, "Timeout waiting for IP ready"); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static void airoha_trng_cleanup(struct hwrng *rng) -+{ -+ struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng); -+ u32 val; -+ -+ val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN); -+ val &= ~RNG_EN; -+ writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN); -+ -+ /* Put it in SW Reset */ -+ writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST); -+} -+ -+static int airoha_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) -+{ -+ struct airoha_trng *trng = container_of(rng, struct airoha_trng, rng); -+ u32 *data = buf; -+ u32 status; -+ int ret; -+ -+ ret = readl_poll_timeout(trng->base + TRNG_HEALTH_TEST_STATUS, status, -+ status & RAW_DATA_VALID, 10, 1000); -+ if (ret < 0) { -+ dev_err(trng->dev, "Timeout waiting for TRNG RAW Data valid\n"); -+ return ret; -+ } -+ -+ *data = readl(trng->base + TRNG_RAW_DATA_OUT); -+ -+ return 4; -+} -+ -+static irqreturn_t airoha_trng_irq(int irq, void *priv) -+{ -+ struct airoha_trng *trng = (struct airoha_trng *)priv; -+ -+ airoha_trng_irq_mask(trng); -+ /* Just complete the task, we will read the value later */ -+ complete(&trng->rng_op_done); -+ -+ return IRQ_HANDLED; -+} -+ -+static int airoha_trng_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct airoha_trng *trng; -+ int irq, ret; -+ u32 val; -+ -+ trng = devm_kzalloc(dev, sizeof(*trng), GFP_KERNEL); -+ if (!trng) -+ return -ENOMEM; -+ -+ trng->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(trng->base)) -+ return PTR_ERR(trng->base); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+ -+ airoha_trng_irq_mask(trng); -+ ret = devm_request_irq(&pdev->dev, irq, airoha_trng_irq, 0, -+ pdev->name, (void *)trng); -+ if (ret) { -+ dev_err(dev, "Can't get interrupt working.\n"); -+ return ret; -+ } -+ -+ init_completion(&trng->rng_op_done); -+ -+ /* Enable interrupt for SW reset Health Check */ -+ val = readl(trng->base + TRNG_INTR_EN); -+ val |= RST_STARTUP_INITR_EN; -+ writel(val, trng->base + TRNG_INTR_EN); -+ -+ /* Set output to raw data */ -+ val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN); -+ val |= RAW_DATA_EN; -+ writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN); -+ -+ /* Put it in SW Reset */ -+ writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST); -+ -+ trng->dev = dev; -+ trng->rng.name = pdev->name; -+ trng->rng.init = airoha_trng_init; -+ trng->rng.cleanup = airoha_trng_cleanup; -+ trng->rng.read = airoha_trng_read; -+ -+ ret = devm_hwrng_register(dev, &trng->rng); -+ if (ret) { -+ dev_err(dev, "failed to register rng device: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id airoha_trng_of_match[] = { -+ { .compatible = "airoha,en7581-trng", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, airoha_trng_of_match); -+ -+static struct platform_driver airoha_trng_driver = { -+ .driver = { -+ .name = "airoha-trng", -+ .of_match_table = airoha_trng_of_match, -+ }, -+ .probe = airoha_trng_probe, -+}; -+ -+module_platform_driver(airoha_trng_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Airoha True Random Number Generator driver"); diff --git a/target/linux/airoha/patches-6.12/031-02-v6.13-net-airoha-Simplify-Tx-napi-logic.patch b/target/linux/airoha/patches-6.12/031-02-v6.13-net-airoha-Simplify-Tx-napi-logic.patch deleted file mode 100644 index 1e907c273d5..00000000000 --- a/target/linux/airoha/patches-6.12/031-02-v6.13-net-airoha-Simplify-Tx-napi-logic.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0c729f53b8c33b9e5eadc2d5e673759e3510501e Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 29 Oct 2024 13:17:10 +0100 -Subject: [PATCH 2/2] net: airoha: Simplify Tx napi logic - -Simplify Tx napi logic relying just on the packet index provided by -completion queue indicating the completed packet that can be removed -from the Tx DMA ring. -This is a preliminary patch to add Qdisc offload for airoha_eth driver. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20241029-airoha-en7581-tx-napi-work-v1-2-96ad1686b946@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 73 ++++++++++++---------- - 1 file changed, 41 insertions(+), 32 deletions(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -1690,8 +1690,12 @@ static int airoha_qdma_tx_napi_poll(stru - irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); - - while (irq_queued > 0 && done < budget) { -- u32 qid, last, val = irq_q->q[head]; -+ u32 qid, val = irq_q->q[head]; -+ struct airoha_qdma_desc *desc; -+ struct airoha_queue_entry *e; - struct airoha_queue *q; -+ u32 index, desc_ctrl; -+ struct sk_buff *skb; - - if (val == 0xff) - break; -@@ -1701,9 +1705,7 @@ static int airoha_qdma_tx_napi_poll(stru - irq_queued--; - done++; - -- last = FIELD_GET(IRQ_DESC_IDX_MASK, val); - qid = FIELD_GET(IRQ_RING_IDX_MASK, val); -- - if (qid >= ARRAY_SIZE(qdma->q_tx)) - continue; - -@@ -1711,46 +1713,53 @@ static int airoha_qdma_tx_napi_poll(stru - if (!q->ndesc) - continue; - -+ index = FIELD_GET(IRQ_DESC_IDX_MASK, val); -+ if (index >= q->ndesc) -+ continue; -+ - spin_lock_bh(&q->lock); - -- while (q->queued > 0) { -- struct airoha_qdma_desc *desc = &q->desc[q->tail]; -- struct airoha_queue_entry *e = &q->entry[q->tail]; -- u32 desc_ctrl = le32_to_cpu(desc->ctrl); -- struct sk_buff *skb = e->skb; -- u16 index = q->tail; -- -- if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && -- !(desc_ctrl & QDMA_DESC_DROP_MASK)) -- break; -+ if (!q->queued) -+ goto unlock; - -- q->tail = (q->tail + 1) % q->ndesc; -- q->queued--; -+ desc = &q->desc[index]; -+ desc_ctrl = le32_to_cpu(desc->ctrl); - -- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, -- DMA_TO_DEVICE); -- -- WRITE_ONCE(desc->msg0, 0); -- WRITE_ONCE(desc->msg1, 0); -+ if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && -+ !(desc_ctrl & QDMA_DESC_DROP_MASK)) -+ goto unlock; -+ -+ e = &q->entry[index]; -+ skb = e->skb; -+ -+ dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, -+ DMA_TO_DEVICE); -+ memset(e, 0, sizeof(*e)); -+ WRITE_ONCE(desc->msg0, 0); -+ WRITE_ONCE(desc->msg1, 0); -+ q->queued--; -+ -+ /* completion ring can report out-of-order indexes if hw QoS -+ * is enabled and packets with different priority are queued -+ * to same DMA ring. Take into account possible out-of-order -+ * reports incrementing DMA ring tail pointer -+ */ -+ while (q->tail != q->head && !q->entry[q->tail].dma_addr) -+ q->tail = (q->tail + 1) % q->ndesc; - -- if (skb) { -- u16 queue = skb_get_queue_mapping(skb); -- struct netdev_queue *txq; -- -- txq = netdev_get_tx_queue(skb->dev, queue); -- netdev_tx_completed_queue(txq, 1, skb->len); -- if (netif_tx_queue_stopped(txq) && -- q->ndesc - q->queued >= q->free_thr) -- netif_tx_wake_queue(txq); -- -- dev_kfree_skb_any(skb); -- e->skb = NULL; -- } -+ if (skb) { -+ u16 queue = skb_get_queue_mapping(skb); -+ struct netdev_queue *txq; -+ -+ txq = netdev_get_tx_queue(skb->dev, queue); -+ netdev_tx_completed_queue(txq, 1, skb->len); -+ if (netif_tx_queue_stopped(txq) && -+ q->ndesc - q->queued >= q->free_thr) -+ netif_tx_wake_queue(txq); - -- if (index == last) -- break; -+ dev_kfree_skb_any(skb); - } -- -+unlock: - spin_unlock_bh(&q->lock); - } - diff --git a/target/linux/airoha/patches-6.12/032-v6.13-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch b/target/linux/airoha/patches-6.12/032-v6.13-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch deleted file mode 100644 index ac65bec2a14..00000000000 --- a/target/linux/airoha/patches-6.12/032-v6.13-watchdog-Add-support-for-Airoha-EN7851-watchdog.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 3cf67f3769b8227ca75ca7102180a2e270ee01aa Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 11 Oct 2024 12:43:53 +0200 -Subject: [PATCH] watchdog: Add support for Airoha EN7851 watchdog - -Add support for Airoha EN7851 watchdog. This is a very basic watchdog -with no pretimeout support, max timeout is 28 seconds and it ticks based -on half the SoC BUS clock. - -Signed-off-by: Christian Marangi -Reviewed-by: Guenter Roeck -Link: https://lore.kernel.org/r/20241011104411.28659-2-ansuelsmth@gmail.com -Signed-off-by: Guenter Roeck -Signed-off-by: Wim Van Sebroeck ---- - drivers/watchdog/Kconfig | 8 ++ - drivers/watchdog/Makefile | 1 + - drivers/watchdog/airoha_wdt.c | 216 ++++++++++++++++++++++++++++++++++ - 3 files changed, 225 insertions(+) - create mode 100644 drivers/watchdog/airoha_wdt.c - ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -408,6 +408,14 @@ config SL28CPLD_WATCHDOG - - # ARM Architecture - -+config AIROHA_WATCHDOG -+ tristate "Airoha EN7581 Watchdog" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ select WATCHDOG_CORE -+ help -+ Watchdog timer embedded into Airoha SoC. This will reboot your -+ system when the timeout is reached. -+ - config ARM_SP805_WATCHDOG - tristate "ARM SP805 Watchdog" - depends on (ARM || ARM64 || COMPILE_TEST) && ARM_AMBA ---- a/drivers/watchdog/Makefile -+++ b/drivers/watchdog/Makefile -@@ -40,6 +40,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb. - obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o - obj-$(CONFIG_ARM_SBSA_WATCHDOG) += sbsa_gwdt.o - obj-$(CONFIG_ARMADA_37XX_WATCHDOG) += armada_37xx_wdt.o -+obj-$(CONFIG_AIROHA_WATCHDOG) += airoha_wdt.o - obj-$(CONFIG_ASM9260_WATCHDOG) += asm9260_wdt.o - obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o - obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o ---- /dev/null -+++ b/drivers/watchdog/airoha_wdt.c -@@ -0,0 +1,216 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Airoha Watchdog Driver -+ * -+ * Copyright (c) 2024, AIROHA All rights reserved. -+ * -+ * Mayur Kumar -+ * Christian Marangi -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Base address of timer and watchdog registers */ -+#define TIMER_CTRL 0x0 -+#define WDT_ENABLE BIT(25) -+#define WDT_TIMER_INTERRUPT BIT(21) -+/* Timer3 is used as Watchdog Timer */ -+#define WDT_TIMER_ENABLE BIT(5) -+#define WDT_TIMER_LOAD_VALUE 0x2c -+#define WDT_TIMER_CUR_VALUE 0x30 -+#define WDT_TIMER_VAL GENMASK(31, 0) -+#define WDT_RELOAD 0x38 -+#define WDT_RLD BIT(0) -+ -+/* Airoha watchdog structure description */ -+struct airoha_wdt_desc { -+ struct watchdog_device wdog_dev; -+ unsigned int wdt_freq; -+ void __iomem *base; -+}; -+ -+#define WDT_HEARTBEAT 24 -+static int heartbeat = WDT_HEARTBEAT; -+module_param(heartbeat, int, 0); -+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default=" -+ __MODULE_STRING(WDT_HEARTBEAT) ")"); -+ -+static bool nowayout = WATCHDOG_NOWAYOUT; -+module_param(nowayout, bool, 0); -+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" -+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -+ -+static int airoha_wdt_start(struct watchdog_device *wdog_dev) -+{ -+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); -+ u32 val; -+ -+ val = readl(airoha_wdt->base + TIMER_CTRL); -+ val |= (WDT_TIMER_ENABLE | WDT_ENABLE | WDT_TIMER_INTERRUPT); -+ writel(val, airoha_wdt->base + TIMER_CTRL); -+ val = wdog_dev->timeout * airoha_wdt->wdt_freq; -+ writel(val, airoha_wdt->base + WDT_TIMER_LOAD_VALUE); -+ -+ return 0; -+} -+ -+static int airoha_wdt_stop(struct watchdog_device *wdog_dev) -+{ -+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); -+ u32 val; -+ -+ val = readl(airoha_wdt->base + TIMER_CTRL); -+ val &= (~WDT_ENABLE & ~WDT_TIMER_ENABLE); -+ writel(val, airoha_wdt->base + TIMER_CTRL); -+ -+ return 0; -+} -+ -+static int airoha_wdt_ping(struct watchdog_device *wdog_dev) -+{ -+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); -+ u32 val; -+ -+ val = readl(airoha_wdt->base + WDT_RELOAD); -+ val |= WDT_RLD; -+ writel(val, airoha_wdt->base + WDT_RELOAD); -+ -+ return 0; -+} -+ -+static int airoha_wdt_set_timeout(struct watchdog_device *wdog_dev, unsigned int timeout) -+{ -+ wdog_dev->timeout = timeout; -+ -+ if (watchdog_active(wdog_dev)) { -+ airoha_wdt_stop(wdog_dev); -+ return airoha_wdt_start(wdog_dev); -+ } -+ -+ return 0; -+} -+ -+static unsigned int airoha_wdt_get_timeleft(struct watchdog_device *wdog_dev) -+{ -+ struct airoha_wdt_desc *airoha_wdt = watchdog_get_drvdata(wdog_dev); -+ u32 val; -+ -+ val = readl(airoha_wdt->base + WDT_TIMER_CUR_VALUE); -+ return DIV_ROUND_UP(val, airoha_wdt->wdt_freq); -+} -+ -+static const struct watchdog_info airoha_wdt_info = { -+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, -+ .identity = "Airoha Watchdog", -+}; -+ -+static const struct watchdog_ops airoha_wdt_ops = { -+ .owner = THIS_MODULE, -+ .start = airoha_wdt_start, -+ .stop = airoha_wdt_stop, -+ .ping = airoha_wdt_ping, -+ .set_timeout = airoha_wdt_set_timeout, -+ .get_timeleft = airoha_wdt_get_timeleft, -+}; -+ -+static int airoha_wdt_probe(struct platform_device *pdev) -+{ -+ struct airoha_wdt_desc *airoha_wdt; -+ struct watchdog_device *wdog_dev; -+ struct device *dev = &pdev->dev; -+ struct clk *bus_clk; -+ int ret; -+ -+ airoha_wdt = devm_kzalloc(dev, sizeof(*airoha_wdt), GFP_KERNEL); -+ if (!airoha_wdt) -+ return -ENOMEM; -+ -+ airoha_wdt->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(airoha_wdt->base)) -+ return PTR_ERR(airoha_wdt->base); -+ -+ bus_clk = devm_clk_get_enabled(dev, "bus"); -+ if (IS_ERR(bus_clk)) -+ return dev_err_probe(dev, PTR_ERR(bus_clk), -+ "failed to enable bus clock\n"); -+ -+ /* Watchdog ticks at half the bus rate */ -+ airoha_wdt->wdt_freq = clk_get_rate(bus_clk) / 2; -+ -+ /* Initialize struct watchdog device */ -+ wdog_dev = &airoha_wdt->wdog_dev; -+ wdog_dev->timeout = heartbeat; -+ wdog_dev->info = &airoha_wdt_info; -+ wdog_dev->ops = &airoha_wdt_ops; -+ /* Bus 300MHz, watchdog 150MHz, 28 seconds */ -+ wdog_dev->max_timeout = FIELD_MAX(WDT_TIMER_VAL) / airoha_wdt->wdt_freq; -+ wdog_dev->parent = dev; -+ -+ watchdog_set_drvdata(wdog_dev, airoha_wdt); -+ watchdog_set_nowayout(wdog_dev, nowayout); -+ watchdog_stop_on_unregister(wdog_dev); -+ -+ ret = devm_watchdog_register_device(dev, wdog_dev); -+ if (ret) -+ return ret; -+ -+ platform_set_drvdata(pdev, airoha_wdt); -+ return 0; -+} -+ -+static int airoha_wdt_suspend(struct device *dev) -+{ -+ struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); -+ -+ if (watchdog_active(&airoha_wdt->wdog_dev)) -+ airoha_wdt_stop(&airoha_wdt->wdog_dev); -+ -+ return 0; -+} -+ -+static int airoha_wdt_resume(struct device *dev) -+{ -+ struct airoha_wdt_desc *airoha_wdt = dev_get_drvdata(dev); -+ -+ if (watchdog_active(&airoha_wdt->wdog_dev)) { -+ airoha_wdt_start(&airoha_wdt->wdog_dev); -+ airoha_wdt_ping(&airoha_wdt->wdog_dev); -+ } -+ return 0; -+} -+ -+static const struct of_device_id airoha_wdt_of_match[] = { -+ { .compatible = "airoha,en7581-wdt", }, -+ { }, -+}; -+ -+MODULE_DEVICE_TABLE(of, airoha_wdt_of_match); -+ -+static DEFINE_SIMPLE_DEV_PM_OPS(airoha_wdt_pm_ops, airoha_wdt_suspend, airoha_wdt_resume); -+ -+static struct platform_driver airoha_wdt_driver = { -+ .probe = airoha_wdt_probe, -+ .driver = { -+ .name = "airoha-wdt", -+ .pm = pm_sleep_ptr(&airoha_wdt_pm_ops), -+ .of_match_table = airoha_wdt_of_match, -+ }, -+}; -+ -+module_platform_driver(airoha_wdt_driver); -+ -+MODULE_AUTHOR("Mayur Kumar "); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Airoha EN7581 Watchdog Driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/033-05-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch b/target/linux/airoha/patches-6.12/033-05-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch deleted file mode 100644 index 6d6868f75a6..00000000000 --- a/target/linux/airoha/patches-6.12/033-05-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 82e6bf912d5846646892becea659b39d178d79e3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 12 Nov 2024 01:08:53 +0100 -Subject: [PATCH 5/6] clk: en7523: move en7581_reset_register() in - en7581_clk_hw_init() - -Move en7581_reset_register routine in en7581_clk_hw_init() since reset -feature is supported just by EN7581 SoC. -Get rid of reset struct in en_clk_soc_data data struct. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-6-8ada5e394ae4@kernel.org -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-en7523.c | 93 ++++++++++++++-------------------------- - 1 file changed, 33 insertions(+), 60 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -76,11 +76,6 @@ struct en_rst_data { - - struct en_clk_soc_data { - const struct clk_ops pcie_ops; -- struct { -- const u16 *bank_ofs; -- const u16 *idx_map; -- u16 idx_map_nr; -- } reset; - int (*hw_init)(struct platform_device *pdev, - struct clk_hw_onecell_data *clk_data); - }; -@@ -596,32 +591,6 @@ static void en7581_register_clocks(struc - clk_data->num = EN7523_NUM_CLOCKS; - } - --static int en7581_clk_hw_init(struct platform_device *pdev, -- struct clk_hw_onecell_data *clk_data) --{ -- void __iomem *np_base; -- struct regmap *map; -- u32 val; -- -- map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); -- if (IS_ERR(map)) -- return PTR_ERR(map); -- -- np_base = devm_platform_ioremap_resource(pdev, 0); -- if (IS_ERR(np_base)) -- return PTR_ERR(np_base); -- -- en7581_register_clocks(&pdev->dev, clk_data, map, np_base); -- -- val = readl(np_base + REG_NP_SCU_SSTR); -- val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); -- writel(val, np_base + REG_NP_SCU_SSTR); -- val = readl(np_base + REG_NP_SCU_PCIC); -- writel(val | 3, np_base + REG_NP_SCU_PCIC); -- -- return 0; --} -- - static int en7523_reset_update(struct reset_controller_dev *rcdev, - unsigned long id, bool assert) - { -@@ -671,23 +640,18 @@ static int en7523_reset_xlate(struct res - return rst_data->idx_map[reset_spec->args[0]]; - } - --static const struct reset_control_ops en7523_reset_ops = { -+static const struct reset_control_ops en7581_reset_ops = { - .assert = en7523_reset_assert, - .deassert = en7523_reset_deassert, - .status = en7523_reset_status, - }; - --static int en7523_reset_register(struct platform_device *pdev, -- const struct en_clk_soc_data *soc_data) -+static int en7581_reset_register(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; - struct en_rst_data *rst_data; - void __iomem *base; - -- /* no reset lines available */ -- if (!soc_data->reset.idx_map_nr) -- return 0; -- - base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(base)) - return PTR_ERR(base); -@@ -696,13 +660,13 @@ static int en7523_reset_register(struct - if (!rst_data) - return -ENOMEM; - -- rst_data->bank_ofs = soc_data->reset.bank_ofs; -- rst_data->idx_map = soc_data->reset.idx_map; -+ rst_data->bank_ofs = en7581_rst_ofs; -+ rst_data->idx_map = en7581_rst_map; - rst_data->base = base; - -- rst_data->rcdev.nr_resets = soc_data->reset.idx_map_nr; -+ rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); - rst_data->rcdev.of_xlate = en7523_reset_xlate; -- rst_data->rcdev.ops = &en7523_reset_ops; -+ rst_data->rcdev.ops = &en7581_reset_ops; - rst_data->rcdev.of_node = dev->of_node; - rst_data->rcdev.of_reset_n_cells = 1; - rst_data->rcdev.owner = THIS_MODULE; -@@ -711,6 +675,32 @@ static int en7523_reset_register(struct - return devm_reset_controller_register(dev, &rst_data->rcdev); - } - -+static int en7581_clk_hw_init(struct platform_device *pdev, -+ struct clk_hw_onecell_data *clk_data) -+{ -+ void __iomem *np_base; -+ struct regmap *map; -+ u32 val; -+ -+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); -+ if (IS_ERR(map)) -+ return PTR_ERR(map); -+ -+ np_base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(np_base)) -+ return PTR_ERR(np_base); -+ -+ en7581_register_clocks(&pdev->dev, clk_data, map, np_base); -+ -+ val = readl(np_base + REG_NP_SCU_SSTR); -+ val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); -+ writel(val, np_base + REG_NP_SCU_SSTR); -+ val = readl(np_base + REG_NP_SCU_PCIC); -+ writel(val | 3, np_base + REG_NP_SCU_PCIC); -+ -+ return en7581_reset_register(pdev); -+} -+ - static int en7523_clk_probe(struct platform_device *pdev) - { - struct device_node *node = pdev->dev.of_node; -@@ -729,19 +719,7 @@ static int en7523_clk_probe(struct platf - if (r) - return r; - -- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); -- if (r) -- return dev_err_probe(&pdev->dev, r, "Could not register clock provider: %s\n", -- pdev->name); -- -- r = en7523_reset_register(pdev, soc_data); -- if (r) { -- of_clk_del_provider(node); -- return dev_err_probe(&pdev->dev, r, "Could not register reset controller: %s\n", -- pdev->name); -- } -- -- return 0; -+ return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); - } - - static const struct en_clk_soc_data en7523_data = { -@@ -759,11 +737,6 @@ static const struct en_clk_soc_data en75 - .enable = en7581_pci_enable, - .disable = en7581_pci_disable, - }, -- .reset = { -- .bank_ofs = en7581_rst_ofs, -- .idx_map = en7581_rst_map, -- .idx_map_nr = ARRAY_SIZE(en7581_rst_map), -- }, - .hw_init = en7581_clk_hw_init, - }; - diff --git a/target/linux/airoha/patches-6.12/033-06-v6.13-clk-en7523-map-io-region-in-a-single-block.patch b/target/linux/airoha/patches-6.12/033-06-v6.13-clk-en7523-map-io-region-in-a-single-block.patch deleted file mode 100644 index 51945a94927..00000000000 --- a/target/linux/airoha/patches-6.12/033-06-v6.13-clk-en7523-map-io-region-in-a-single-block.patch +++ /dev/null @@ -1,84 +0,0 @@ -From a9eaf305017a5ebe73ab34e85bd5414055a88f29 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 12 Nov 2024 01:08:54 +0100 -Subject: [PATCH 6/6] clk: en7523: map io region in a single block - -Map all clock-controller memory region in a single block. -This patch does not introduce any backward incompatibility since the dts -for EN7581 SoC is not upstream yet. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-7-8ada5e394ae4@kernel.org -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-en7523.c | 32 +++++++++++++------------------- - 1 file changed, 13 insertions(+), 19 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -39,8 +39,8 @@ - #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) - #define REG_CRYPTO_CLKSRC2 0x20c - --#define REG_RST_CTRL2 0x00 --#define REG_RST_CTRL1 0x04 -+#define REG_RST_CTRL2 0x830 -+#define REG_RST_CTRL1 0x834 - - struct en_clk_desc { - int id; -@@ -646,15 +646,9 @@ static const struct reset_control_ops en - .status = en7523_reset_status, - }; - --static int en7581_reset_register(struct platform_device *pdev) -+static int en7581_reset_register(struct device *dev, void __iomem *base) - { -- struct device *dev = &pdev->dev; - struct en_rst_data *rst_data; -- void __iomem *base; -- -- base = devm_platform_ioremap_resource(pdev, 1); -- if (IS_ERR(base)) -- return PTR_ERR(base); - - rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); - if (!rst_data) -@@ -678,27 +672,27 @@ static int en7581_reset_register(struct - static int en7581_clk_hw_init(struct platform_device *pdev, - struct clk_hw_onecell_data *clk_data) - { -- void __iomem *np_base; - struct regmap *map; -+ void __iomem *base; - u32 val; - - map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); - if (IS_ERR(map)) - return PTR_ERR(map); - -- np_base = devm_platform_ioremap_resource(pdev, 0); -- if (IS_ERR(np_base)) -- return PTR_ERR(np_base); -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); - -- en7581_register_clocks(&pdev->dev, clk_data, map, np_base); -+ en7581_register_clocks(&pdev->dev, clk_data, map, base); - -- val = readl(np_base + REG_NP_SCU_SSTR); -+ val = readl(base + REG_NP_SCU_SSTR); - val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); -- writel(val, np_base + REG_NP_SCU_SSTR); -- val = readl(np_base + REG_NP_SCU_PCIC); -- writel(val | 3, np_base + REG_NP_SCU_PCIC); -+ writel(val, base + REG_NP_SCU_SSTR); -+ val = readl(base + REG_NP_SCU_PCIC); -+ writel(val | 3, base + REG_NP_SCU_PCIC); - -- return en7581_reset_register(pdev); -+ return en7581_reset_register(&pdev->dev, base); - } - - static int en7523_clk_probe(struct platform_device *pdev) diff --git a/target/linux/airoha/patches-6.12/034-01-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.12/034-01-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch deleted file mode 100644 index ceb58a1b00d..00000000000 --- a/target/linux/airoha/patches-6.12/034-01-v6.13-pinctrl-airoha-Add-support-for-EN7581-SoC.patch +++ /dev/null @@ -1,3060 +0,0 @@ -From 1c8ace2d0725c1c8d5012f8a56c5fb31805aad27 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 23 Oct 2024 01:20:05 +0200 -Subject: [PATCH] pinctrl: airoha: Add support for EN7581 SoC - -Introduce pinctrl driver for EN7581 SoC. Current EN7581 pinctrl driver -supports the following functionalities: -- pin multiplexing -- pin pull-up, pull-down, open-drain, current strength, - {input,output}_enable, output_{low,high} -- gpio controller -- irq controller - -Tested-by: Benjamin Larsson -Co-developed-by: Benjamin Larsson -Signed-off-by: Benjamin Larsson -Reviewed-by: Linus Walleij -Reviewed-by: AngeloGioacchino Del Regno -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/20241023-en7581-pinctrl-v9-5-afb0cbcab0ec@kernel.org -Signed-off-by: Linus Walleij ---- - MAINTAINERS | 7 + - drivers/pinctrl/mediatek/Kconfig | 17 +- - drivers/pinctrl/mediatek/Makefile | 1 + - drivers/pinctrl/mediatek/pinctrl-airoha.c | 2970 +++++++++++++++++++++ - 4 files changed, 2994 insertions(+), 1 deletion(-) - create mode 100644 drivers/pinctrl/mediatek/pinctrl-airoha.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -18204,6 +18204,13 @@ F: drivers/pinctrl/ - F: include/dt-bindings/pinctrl/ - F: include/linux/pinctrl/ - -+PIN CONTROLLER - AIROHA -+M: Lorenzo Bianconi -+L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) -+S: Maintained -+F: Documentation/devicetree/bindings/pinctrl/airoha,en7581-pinctrl.yaml -+F: drivers/pinctrl/mediatek/pinctrl-airoha.c -+ - PIN CONTROLLER - AMD - M: Basavaraj Natikar - M: Shyam Sundar S K ---- a/drivers/pinctrl/mediatek/Kconfig -+++ b/drivers/pinctrl/mediatek/Kconfig -@@ -1,6 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0-only - menu "MediaTek pinctrl drivers" -- depends on ARCH_MEDIATEK || RALINK || COMPILE_TEST -+ depends on ARCH_MEDIATEK || ARCH_AIROHA || RALINK || COMPILE_TEST - - config EINT_MTK - tristate "MediaTek External Interrupt Support" -@@ -126,6 +126,21 @@ config PINCTRL_MT8127 - select PINCTRL_MTK - - # For ARMv8 SoCs -+config PINCTRL_AIROHA -+ tristate "Airoha EN7581 pin control" -+ depends on OF -+ depends on ARM64 || COMPILE_TEST -+ select PINMUX -+ select GENERIC_PINCONF -+ select GENERIC_PINCTRL_GROUPS -+ select GENERIC_PINMUX_FUNCTIONS -+ select GPIOLIB -+ select GPIOLIB_IRQCHIP -+ select REGMAP_MMIO -+ help -+ Say yes here to support pin controller and gpio driver -+ on Airoha EN7581 SoC. -+ - config PINCTRL_MT2712 - bool "MediaTek MT2712 pin control" - depends on OF ---- a/drivers/pinctrl/mediatek/Makefile -+++ b/drivers/pinctrl/mediatek/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_MTK_MOORE) += pinc - obj-$(CONFIG_PINCTRL_MTK_PARIS) += pinctrl-paris.o - - # SoC Drivers -+obj-$(CONFIG_PINCTRL_AIROHA) += pinctrl-airoha.o - obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o - obj-$(CONFIG_PINCTRL_MT7621) += pinctrl-mt7621.o - obj-$(CONFIG_PINCTRL_MT76X8) += pinctrl-mt76x8.o ---- /dev/null -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -0,0 +1,2970 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Author: Lorenzo Bianconi -+ * Author: Benjamin Larsson -+ * Author: Markus Gothe -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../core.h" -+#include "../pinconf.h" -+#include "../pinmux.h" -+ -+#define PINCTRL_PIN_GROUP(id) \ -+ PINCTRL_PINGROUP(#id, id##_pins, ARRAY_SIZE(id##_pins)) -+ -+#define PINCTRL_FUNC_DESC(id) \ -+ { \ -+ .desc = { \ -+ .func = { \ -+ .name = #id, \ -+ .groups = id##_groups, \ -+ .ngroups = ARRAY_SIZE(id##_groups), \ -+ } \ -+ }, \ -+ .groups = id##_func_group, \ -+ .group_size = ARRAY_SIZE(id##_func_group), \ -+ } -+ -+#define PINCTRL_CONF_DESC(p, offset, mask) \ -+ { \ -+ .pin = p, \ -+ .reg = { offset, mask }, \ -+ } -+ -+/* MUX */ -+#define REG_GPIO_2ND_I2C_MODE 0x0214 -+#define GPIO_MDC_IO_MASTER_MODE_MODE BIT(14) -+#define GPIO_I2C_MASTER_MODE_MODE BIT(13) -+#define GPIO_I2S_MODE_MASK BIT(12) -+#define GPIO_I2C_SLAVE_MODE_MODE BIT(11) -+#define GPIO_LAN3_LED1_MODE_MASK BIT(10) -+#define GPIO_LAN3_LED0_MODE_MASK BIT(9) -+#define GPIO_LAN2_LED1_MODE_MASK BIT(8) -+#define GPIO_LAN2_LED0_MODE_MASK BIT(7) -+#define GPIO_LAN1_LED1_MODE_MASK BIT(6) -+#define GPIO_LAN1_LED0_MODE_MASK BIT(5) -+#define GPIO_LAN0_LED1_MODE_MASK BIT(4) -+#define GPIO_LAN0_LED0_MODE_MASK BIT(3) -+#define PON_TOD_1PPS_MODE_MASK BIT(2) -+#define GSW_TOD_1PPS_MODE_MASK BIT(1) -+#define GPIO_2ND_I2C_MODE_MASK BIT(0) -+ -+#define REG_GPIO_SPI_CS1_MODE 0x0218 -+#define GPIO_PCM_SPI_CS4_MODE_MASK BIT(21) -+#define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20) -+#define GPIO_PCM_SPI_CS2_MODE_P156_MASK BIT(19) -+#define GPIO_PCM_SPI_CS2_MODE_P128_MASK BIT(18) -+#define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17) -+#define GPIO_PCM_SPI_MODE_MASK BIT(16) -+#define GPIO_PCM2_MODE_MASK BIT(13) -+#define GPIO_PCM1_MODE_MASK BIT(12) -+#define GPIO_PCM_INT_MODE_MASK BIT(9) -+#define GPIO_PCM_RESET_MODE_MASK BIT(8) -+#define GPIO_SPI_QUAD_MODE_MASK BIT(4) -+#define GPIO_SPI_CS4_MODE_MASK BIT(3) -+#define GPIO_SPI_CS3_MODE_MASK BIT(2) -+#define GPIO_SPI_CS2_MODE_MASK BIT(1) -+#define GPIO_SPI_CS1_MODE_MASK BIT(0) -+ -+#define REG_GPIO_PON_MODE 0x021c -+#define GPIO_PARALLEL_NAND_MODE_MASK BIT(14) -+#define GPIO_SGMII_MDIO_MODE_MASK BIT(13) -+#define GPIO_PCIE_RESET2_MASK BIT(12) -+#define SIPO_RCLK_MODE_MASK BIT(11) -+#define GPIO_PCIE_RESET1_MASK BIT(10) -+#define GPIO_PCIE_RESET0_MASK BIT(9) -+#define GPIO_UART5_MODE_MASK BIT(8) -+#define GPIO_UART4_MODE_MASK BIT(7) -+#define GPIO_HSUART_CTS_RTS_MODE_MASK BIT(6) -+#define GPIO_HSUART_MODE_MASK BIT(5) -+#define GPIO_UART2_CTS_RTS_MODE_MASK BIT(4) -+#define GPIO_UART2_MODE_MASK BIT(3) -+#define GPIO_SIPO_MODE_MASK BIT(2) -+#define GPIO_EMMC_MODE_MASK BIT(1) -+#define GPIO_PON_MODE_MASK BIT(0) -+ -+#define REG_NPU_UART_EN 0x0224 -+#define JTAG_UDI_EN_MASK BIT(4) -+#define JTAG_DFD_EN_MASK BIT(3) -+ -+/* LED MAP */ -+#define REG_LAN_LED0_MAPPING 0x027c -+#define REG_LAN_LED1_MAPPING 0x0280 -+ -+#define LAN4_LED_MAPPING_MASK GENMASK(18, 16) -+#define LAN4_PHY4_LED_MAP BIT(18) -+#define LAN4_PHY2_LED_MAP BIT(17) -+#define LAN4_PHY1_LED_MAP BIT(16) -+#define LAN4_PHY0_LED_MAP 0 -+#define LAN4_PHY3_LED_MAP GENMASK(17, 16) -+ -+#define LAN3_LED_MAPPING_MASK GENMASK(14, 12) -+#define LAN3_PHY4_LED_MAP BIT(14) -+#define LAN3_PHY2_LED_MAP BIT(13) -+#define LAN3_PHY1_LED_MAP BIT(12) -+#define LAN3_PHY0_LED_MAP 0 -+#define LAN3_PHY3_LED_MAP GENMASK(13, 12) -+ -+#define LAN2_LED_MAPPING_MASK GENMASK(10, 8) -+#define LAN2_PHY4_LED_MAP BIT(12) -+#define LAN2_PHY2_LED_MAP BIT(11) -+#define LAN2_PHY1_LED_MAP BIT(10) -+#define LAN2_PHY0_LED_MAP 0 -+#define LAN2_PHY3_LED_MAP GENMASK(11, 10) -+ -+#define LAN1_LED_MAPPING_MASK GENMASK(6, 4) -+#define LAN1_PHY4_LED_MAP BIT(6) -+#define LAN1_PHY2_LED_MAP BIT(5) -+#define LAN1_PHY1_LED_MAP BIT(4) -+#define LAN1_PHY0_LED_MAP 0 -+#define LAN1_PHY3_LED_MAP GENMASK(5, 4) -+ -+#define LAN0_LED_MAPPING_MASK GENMASK(2, 0) -+#define LAN0_PHY4_LED_MAP BIT(3) -+#define LAN0_PHY2_LED_MAP BIT(2) -+#define LAN0_PHY1_LED_MAP BIT(1) -+#define LAN0_PHY0_LED_MAP 0 -+#define LAN0_PHY3_LED_MAP GENMASK(2, 1) -+ -+/* CONF */ -+#define REG_I2C_SDA_E2 0x001c -+#define SPI_MISO_E2_MASK BIT(14) -+#define SPI_MOSI_E2_MASK BIT(13) -+#define SPI_CLK_E2_MASK BIT(12) -+#define SPI_CS0_E2_MASK BIT(11) -+#define PCIE2_RESET_E2_MASK BIT(10) -+#define PCIE1_RESET_E2_MASK BIT(9) -+#define PCIE0_RESET_E2_MASK BIT(8) -+#define UART1_RXD_E2_MASK BIT(3) -+#define UART1_TXD_E2_MASK BIT(2) -+#define I2C_SCL_E2_MASK BIT(1) -+#define I2C_SDA_E2_MASK BIT(0) -+ -+#define REG_I2C_SDA_E4 0x0020 -+#define SPI_MISO_E4_MASK BIT(14) -+#define SPI_MOSI_E4_MASK BIT(13) -+#define SPI_CLK_E4_MASK BIT(12) -+#define SPI_CS0_E4_MASK BIT(11) -+#define PCIE2_RESET_E4_MASK BIT(10) -+#define PCIE1_RESET_E4_MASK BIT(9) -+#define PCIE0_RESET_E4_MASK BIT(8) -+#define UART1_RXD_E4_MASK BIT(3) -+#define UART1_TXD_E4_MASK BIT(2) -+#define I2C_SCL_E4_MASK BIT(1) -+#define I2C_SDA_E4_MASK BIT(0) -+ -+#define REG_GPIO_L_E2 0x0024 -+#define REG_GPIO_L_E4 0x0028 -+#define REG_GPIO_H_E2 0x002c -+#define REG_GPIO_H_E4 0x0030 -+ -+#define REG_I2C_SDA_PU 0x0044 -+#define SPI_MISO_PU_MASK BIT(14) -+#define SPI_MOSI_PU_MASK BIT(13) -+#define SPI_CLK_PU_MASK BIT(12) -+#define SPI_CS0_PU_MASK BIT(11) -+#define PCIE2_RESET_PU_MASK BIT(10) -+#define PCIE1_RESET_PU_MASK BIT(9) -+#define PCIE0_RESET_PU_MASK BIT(8) -+#define UART1_RXD_PU_MASK BIT(3) -+#define UART1_TXD_PU_MASK BIT(2) -+#define I2C_SCL_PU_MASK BIT(1) -+#define I2C_SDA_PU_MASK BIT(0) -+ -+#define REG_I2C_SDA_PD 0x0048 -+#define SPI_MISO_PD_MASK BIT(14) -+#define SPI_MOSI_PD_MASK BIT(13) -+#define SPI_CLK_PD_MASK BIT(12) -+#define SPI_CS0_PD_MASK BIT(11) -+#define PCIE2_RESET_PD_MASK BIT(10) -+#define PCIE1_RESET_PD_MASK BIT(9) -+#define PCIE0_RESET_PD_MASK BIT(8) -+#define UART1_RXD_PD_MASK BIT(3) -+#define UART1_TXD_PD_MASK BIT(2) -+#define I2C_SCL_PD_MASK BIT(1) -+#define I2C_SDA_PD_MASK BIT(0) -+ -+#define REG_GPIO_L_PU 0x004c -+#define REG_GPIO_L_PD 0x0050 -+#define REG_GPIO_H_PU 0x0054 -+#define REG_GPIO_H_PD 0x0058 -+ -+#define REG_PCIE_RESET_OD 0x018c -+#define PCIE2_RESET_OD_MASK BIT(2) -+#define PCIE1_RESET_OD_MASK BIT(1) -+#define PCIE0_RESET_OD_MASK BIT(0) -+ -+/* GPIOs */ -+#define REG_GPIO_CTRL 0x0000 -+#define REG_GPIO_DATA 0x0004 -+#define REG_GPIO_INT 0x0008 -+#define REG_GPIO_INT_EDGE 0x000c -+#define REG_GPIO_INT_LEVEL 0x0010 -+#define REG_GPIO_OE 0x0014 -+#define REG_GPIO_CTRL1 0x0020 -+ -+/* PWM MODE CONF */ -+#define REG_GPIO_FLASH_MODE_CFG 0x0034 -+#define GPIO15_FLASH_MODE_CFG BIT(15) -+#define GPIO14_FLASH_MODE_CFG BIT(14) -+#define GPIO13_FLASH_MODE_CFG BIT(13) -+#define GPIO12_FLASH_MODE_CFG BIT(12) -+#define GPIO11_FLASH_MODE_CFG BIT(11) -+#define GPIO10_FLASH_MODE_CFG BIT(10) -+#define GPIO9_FLASH_MODE_CFG BIT(9) -+#define GPIO8_FLASH_MODE_CFG BIT(8) -+#define GPIO7_FLASH_MODE_CFG BIT(7) -+#define GPIO6_FLASH_MODE_CFG BIT(6) -+#define GPIO5_FLASH_MODE_CFG BIT(5) -+#define GPIO4_FLASH_MODE_CFG BIT(4) -+#define GPIO3_FLASH_MODE_CFG BIT(3) -+#define GPIO2_FLASH_MODE_CFG BIT(2) -+#define GPIO1_FLASH_MODE_CFG BIT(1) -+#define GPIO0_FLASH_MODE_CFG BIT(0) -+ -+#define REG_GPIO_CTRL2 0x0060 -+#define REG_GPIO_CTRL3 0x0064 -+ -+/* PWM MODE CONF EXT */ -+#define REG_GPIO_FLASH_MODE_CFG_EXT 0x0068 -+#define GPIO51_FLASH_MODE_CFG BIT(31) -+#define GPIO50_FLASH_MODE_CFG BIT(30) -+#define GPIO49_FLASH_MODE_CFG BIT(29) -+#define GPIO48_FLASH_MODE_CFG BIT(28) -+#define GPIO47_FLASH_MODE_CFG BIT(27) -+#define GPIO46_FLASH_MODE_CFG BIT(26) -+#define GPIO45_FLASH_MODE_CFG BIT(25) -+#define GPIO44_FLASH_MODE_CFG BIT(24) -+#define GPIO43_FLASH_MODE_CFG BIT(23) -+#define GPIO42_FLASH_MODE_CFG BIT(22) -+#define GPIO41_FLASH_MODE_CFG BIT(21) -+#define GPIO40_FLASH_MODE_CFG BIT(20) -+#define GPIO39_FLASH_MODE_CFG BIT(19) -+#define GPIO38_FLASH_MODE_CFG BIT(18) -+#define GPIO37_FLASH_MODE_CFG BIT(17) -+#define GPIO36_FLASH_MODE_CFG BIT(16) -+#define GPIO31_FLASH_MODE_CFG BIT(15) -+#define GPIO30_FLASH_MODE_CFG BIT(14) -+#define GPIO29_FLASH_MODE_CFG BIT(13) -+#define GPIO28_FLASH_MODE_CFG BIT(12) -+#define GPIO27_FLASH_MODE_CFG BIT(11) -+#define GPIO26_FLASH_MODE_CFG BIT(10) -+#define GPIO25_FLASH_MODE_CFG BIT(9) -+#define GPIO24_FLASH_MODE_CFG BIT(8) -+#define GPIO23_FLASH_MODE_CFG BIT(7) -+#define GPIO22_FLASH_MODE_CFG BIT(6) -+#define GPIO21_FLASH_MODE_CFG BIT(5) -+#define GPIO20_FLASH_MODE_CFG BIT(4) -+#define GPIO19_FLASH_MODE_CFG BIT(3) -+#define GPIO18_FLASH_MODE_CFG BIT(2) -+#define GPIO17_FLASH_MODE_CFG BIT(1) -+#define GPIO16_FLASH_MODE_CFG BIT(0) -+ -+#define REG_GPIO_DATA1 0x0070 -+#define REG_GPIO_OE1 0x0078 -+#define REG_GPIO_INT1 0x007c -+#define REG_GPIO_INT_EDGE1 0x0080 -+#define REG_GPIO_INT_EDGE2 0x0084 -+#define REG_GPIO_INT_EDGE3 0x0088 -+#define REG_GPIO_INT_LEVEL1 0x008c -+#define REG_GPIO_INT_LEVEL2 0x0090 -+#define REG_GPIO_INT_LEVEL3 0x0094 -+ -+#define AIROHA_NUM_PINS 64 -+#define AIROHA_PIN_BANK_SIZE (AIROHA_NUM_PINS / 2) -+#define AIROHA_REG_GPIOCTRL_NUM_PIN (AIROHA_NUM_PINS / 4) -+ -+static const u32 gpio_data_regs[] = { -+ REG_GPIO_DATA, -+ REG_GPIO_DATA1 -+}; -+ -+static const u32 gpio_out_regs[] = { -+ REG_GPIO_OE, -+ REG_GPIO_OE1 -+}; -+ -+static const u32 gpio_dir_regs[] = { -+ REG_GPIO_CTRL, -+ REG_GPIO_CTRL1, -+ REG_GPIO_CTRL2, -+ REG_GPIO_CTRL3 -+}; -+ -+static const u32 irq_status_regs[] = { -+ REG_GPIO_INT, -+ REG_GPIO_INT1 -+}; -+ -+static const u32 irq_level_regs[] = { -+ REG_GPIO_INT_LEVEL, -+ REG_GPIO_INT_LEVEL1, -+ REG_GPIO_INT_LEVEL2, -+ REG_GPIO_INT_LEVEL3 -+}; -+ -+static const u32 irq_edge_regs[] = { -+ REG_GPIO_INT_EDGE, -+ REG_GPIO_INT_EDGE1, -+ REG_GPIO_INT_EDGE2, -+ REG_GPIO_INT_EDGE3 -+}; -+ -+struct airoha_pinctrl_reg { -+ u32 offset; -+ u32 mask; -+}; -+ -+enum airoha_pinctrl_mux_func { -+ AIROHA_FUNC_MUX, -+ AIROHA_FUNC_PWM_MUX, -+ AIROHA_FUNC_PWM_EXT_MUX, -+}; -+ -+struct airoha_pinctrl_func_group { -+ const char *name; -+ struct { -+ enum airoha_pinctrl_mux_func mux; -+ u32 offset; -+ u32 mask; -+ u32 val; -+ } regmap[2]; -+ int regmap_size; -+}; -+ -+struct airoha_pinctrl_func { -+ const struct function_desc desc; -+ const struct airoha_pinctrl_func_group *groups; -+ u8 group_size; -+}; -+ -+struct airoha_pinctrl_conf { -+ u32 pin; -+ struct airoha_pinctrl_reg reg; -+}; -+ -+struct airoha_pinctrl_gpiochip { -+ struct gpio_chip chip; -+ -+ /* gpio */ -+ const u32 *data; -+ const u32 *dir; -+ const u32 *out; -+ /* irq */ -+ const u32 *status; -+ const u32 *level; -+ const u32 *edge; -+ -+ u32 irq_type[AIROHA_NUM_PINS]; -+}; -+ -+struct airoha_pinctrl { -+ struct pinctrl_dev *ctrl; -+ -+ struct regmap *chip_scu; -+ struct regmap *regmap; -+ -+ struct airoha_pinctrl_gpiochip gpiochip; -+}; -+ -+static struct pinctrl_pin_desc airoha_pinctrl_pins[] = { -+ PINCTRL_PIN(0, "uart1_txd"), -+ PINCTRL_PIN(1, "uart1_rxd"), -+ PINCTRL_PIN(2, "i2c_scl"), -+ PINCTRL_PIN(3, "i2c_sda"), -+ PINCTRL_PIN(4, "spi_cs0"), -+ PINCTRL_PIN(5, "spi_clk"), -+ PINCTRL_PIN(6, "spi_mosi"), -+ PINCTRL_PIN(7, "spi_miso"), -+ PINCTRL_PIN(13, "gpio0"), -+ PINCTRL_PIN(14, "gpio1"), -+ PINCTRL_PIN(15, "gpio2"), -+ PINCTRL_PIN(16, "gpio3"), -+ PINCTRL_PIN(17, "gpio4"), -+ PINCTRL_PIN(18, "gpio5"), -+ PINCTRL_PIN(19, "gpio6"), -+ PINCTRL_PIN(20, "gpio7"), -+ PINCTRL_PIN(21, "gpio8"), -+ PINCTRL_PIN(22, "gpio9"), -+ PINCTRL_PIN(23, "gpio10"), -+ PINCTRL_PIN(24, "gpio11"), -+ PINCTRL_PIN(25, "gpio12"), -+ PINCTRL_PIN(26, "gpio13"), -+ PINCTRL_PIN(27, "gpio14"), -+ PINCTRL_PIN(28, "gpio15"), -+ PINCTRL_PIN(29, "gpio16"), -+ PINCTRL_PIN(30, "gpio17"), -+ PINCTRL_PIN(31, "gpio18"), -+ PINCTRL_PIN(32, "gpio19"), -+ PINCTRL_PIN(33, "gpio20"), -+ PINCTRL_PIN(34, "gpio21"), -+ PINCTRL_PIN(35, "gpio22"), -+ PINCTRL_PIN(36, "gpio23"), -+ PINCTRL_PIN(37, "gpio24"), -+ PINCTRL_PIN(38, "gpio25"), -+ PINCTRL_PIN(39, "gpio26"), -+ PINCTRL_PIN(40, "gpio27"), -+ PINCTRL_PIN(41, "gpio28"), -+ PINCTRL_PIN(42, "gpio29"), -+ PINCTRL_PIN(43, "gpio30"), -+ PINCTRL_PIN(44, "gpio31"), -+ PINCTRL_PIN(45, "gpio32"), -+ PINCTRL_PIN(46, "gpio33"), -+ PINCTRL_PIN(47, "gpio34"), -+ PINCTRL_PIN(48, "gpio35"), -+ PINCTRL_PIN(49, "gpio36"), -+ PINCTRL_PIN(50, "gpio37"), -+ PINCTRL_PIN(51, "gpio38"), -+ PINCTRL_PIN(52, "gpio39"), -+ PINCTRL_PIN(53, "gpio40"), -+ PINCTRL_PIN(54, "gpio41"), -+ PINCTRL_PIN(55, "gpio42"), -+ PINCTRL_PIN(56, "gpio43"), -+ PINCTRL_PIN(57, "gpio44"), -+ PINCTRL_PIN(58, "gpio45"), -+ PINCTRL_PIN(59, "gpio46"), -+ PINCTRL_PIN(61, "pcie_reset0"), -+ PINCTRL_PIN(62, "pcie_reset1"), -+ PINCTRL_PIN(63, "pcie_reset2"), -+}; -+ -+static const int pon_pins[] = { 49, 50, 51, 52, 53, 54 }; -+static const int pon_tod_1pps_pins[] = { 46 }; -+static const int gsw_tod_1pps_pins[] = { 46 }; -+static const int sipo_pins[] = { 16, 17 }; -+static const int sipo_rclk_pins[] = { 16, 17, 43 }; -+static const int mdio_pins[] = { 14, 15 }; -+static const int uart2_pins[] = { 48, 55 }; -+static const int uart2_cts_rts_pins[] = { 46, 47 }; -+static const int hsuart_pins[] = { 28, 29 }; -+static const int hsuart_cts_rts_pins[] = { 26, 27 }; -+static const int uart4_pins[] = { 38, 39 }; -+static const int uart5_pins[] = { 18, 19 }; -+static const int i2c0_pins[] = { 2, 3 }; -+static const int i2c1_pins[] = { 14, 15 }; -+static const int jtag_udi_pins[] = { 16, 17, 18, 19, 20 }; -+static const int jtag_dfd_pins[] = { 16, 17, 18, 19, 20 }; -+static const int i2s_pins[] = { 26, 27, 28, 29 }; -+static const int pcm1_pins[] = { 22, 23, 24, 25 }; -+static const int pcm2_pins[] = { 18, 19, 20, 21 }; -+static const int spi_quad_pins[] = { 32, 33 }; -+static const int spi_pins[] = { 4, 5, 6, 7 }; -+static const int spi_cs1_pins[] = { 34 }; -+static const int pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 }; -+static const int pcm_spi_int_pins[] = { 14 }; -+static const int pcm_spi_rst_pins[] = { 15 }; -+static const int pcm_spi_cs1_pins[] = { 43 }; -+static const int pcm_spi_cs2_pins[] = { 40 }; -+static const int pcm_spi_cs2_p128_pins[] = { 40 }; -+static const int pcm_spi_cs2_p156_pins[] = { 40 }; -+static const int pcm_spi_cs3_pins[] = { 41 }; -+static const int pcm_spi_cs4_pins[] = { 42 }; -+static const int emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 }; -+static const int pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 }; -+static const int gpio0_pins[] = { 13 }; -+static const int gpio1_pins[] = { 14 }; -+static const int gpio2_pins[] = { 15 }; -+static const int gpio3_pins[] = { 16 }; -+static const int gpio4_pins[] = { 17 }; -+static const int gpio5_pins[] = { 18 }; -+static const int gpio6_pins[] = { 19 }; -+static const int gpio7_pins[] = { 20 }; -+static const int gpio8_pins[] = { 21 }; -+static const int gpio9_pins[] = { 22 }; -+static const int gpio10_pins[] = { 23 }; -+static const int gpio11_pins[] = { 24 }; -+static const int gpio12_pins[] = { 25 }; -+static const int gpio13_pins[] = { 26 }; -+static const int gpio14_pins[] = { 27 }; -+static const int gpio15_pins[] = { 28 }; -+static const int gpio16_pins[] = { 29 }; -+static const int gpio17_pins[] = { 30 }; -+static const int gpio18_pins[] = { 31 }; -+static const int gpio19_pins[] = { 32 }; -+static const int gpio20_pins[] = { 33 }; -+static const int gpio21_pins[] = { 34 }; -+static const int gpio22_pins[] = { 35 }; -+static const int gpio23_pins[] = { 36 }; -+static const int gpio24_pins[] = { 37 }; -+static const int gpio25_pins[] = { 38 }; -+static const int gpio26_pins[] = { 39 }; -+static const int gpio27_pins[] = { 40 }; -+static const int gpio28_pins[] = { 41 }; -+static const int gpio29_pins[] = { 42 }; -+static const int gpio30_pins[] = { 43 }; -+static const int gpio31_pins[] = { 44 }; -+static const int gpio33_pins[] = { 46 }; -+static const int gpio34_pins[] = { 47 }; -+static const int gpio35_pins[] = { 48 }; -+static const int gpio36_pins[] = { 49 }; -+static const int gpio37_pins[] = { 50 }; -+static const int gpio38_pins[] = { 51 }; -+static const int gpio39_pins[] = { 52 }; -+static const int gpio40_pins[] = { 53 }; -+static const int gpio41_pins[] = { 54 }; -+static const int gpio42_pins[] = { 55 }; -+static const int gpio43_pins[] = { 56 }; -+static const int gpio44_pins[] = { 57 }; -+static const int gpio45_pins[] = { 58 }; -+static const int gpio46_pins[] = { 59 }; -+static const int pcie_reset0_pins[] = { 61 }; -+static const int pcie_reset1_pins[] = { 62 }; -+static const int pcie_reset2_pins[] = { 63 }; -+ -+static const struct pingroup airoha_pinctrl_groups[] = { -+ PINCTRL_PIN_GROUP(pon), -+ PINCTRL_PIN_GROUP(pon_tod_1pps), -+ PINCTRL_PIN_GROUP(gsw_tod_1pps), -+ PINCTRL_PIN_GROUP(sipo), -+ PINCTRL_PIN_GROUP(sipo_rclk), -+ PINCTRL_PIN_GROUP(mdio), -+ PINCTRL_PIN_GROUP(uart2), -+ PINCTRL_PIN_GROUP(uart2_cts_rts), -+ PINCTRL_PIN_GROUP(hsuart), -+ PINCTRL_PIN_GROUP(hsuart_cts_rts), -+ PINCTRL_PIN_GROUP(uart4), -+ PINCTRL_PIN_GROUP(uart5), -+ PINCTRL_PIN_GROUP(i2c0), -+ PINCTRL_PIN_GROUP(i2c1), -+ PINCTRL_PIN_GROUP(jtag_udi), -+ PINCTRL_PIN_GROUP(jtag_dfd), -+ PINCTRL_PIN_GROUP(i2s), -+ PINCTRL_PIN_GROUP(pcm1), -+ PINCTRL_PIN_GROUP(pcm2), -+ PINCTRL_PIN_GROUP(spi), -+ PINCTRL_PIN_GROUP(spi_quad), -+ PINCTRL_PIN_GROUP(spi_cs1), -+ PINCTRL_PIN_GROUP(pcm_spi), -+ PINCTRL_PIN_GROUP(pcm_spi_int), -+ PINCTRL_PIN_GROUP(pcm_spi_rst), -+ PINCTRL_PIN_GROUP(pcm_spi_cs1), -+ PINCTRL_PIN_GROUP(pcm_spi_cs2_p128), -+ PINCTRL_PIN_GROUP(pcm_spi_cs2_p156), -+ PINCTRL_PIN_GROUP(pcm_spi_cs2), -+ PINCTRL_PIN_GROUP(pcm_spi_cs3), -+ PINCTRL_PIN_GROUP(pcm_spi_cs4), -+ PINCTRL_PIN_GROUP(emmc), -+ PINCTRL_PIN_GROUP(pnand), -+ PINCTRL_PIN_GROUP(gpio0), -+ PINCTRL_PIN_GROUP(gpio1), -+ PINCTRL_PIN_GROUP(gpio2), -+ PINCTRL_PIN_GROUP(gpio3), -+ PINCTRL_PIN_GROUP(gpio4), -+ PINCTRL_PIN_GROUP(gpio5), -+ PINCTRL_PIN_GROUP(gpio6), -+ PINCTRL_PIN_GROUP(gpio7), -+ PINCTRL_PIN_GROUP(gpio8), -+ PINCTRL_PIN_GROUP(gpio9), -+ PINCTRL_PIN_GROUP(gpio10), -+ PINCTRL_PIN_GROUP(gpio11), -+ PINCTRL_PIN_GROUP(gpio12), -+ PINCTRL_PIN_GROUP(gpio13), -+ PINCTRL_PIN_GROUP(gpio14), -+ PINCTRL_PIN_GROUP(gpio15), -+ PINCTRL_PIN_GROUP(gpio16), -+ PINCTRL_PIN_GROUP(gpio17), -+ PINCTRL_PIN_GROUP(gpio18), -+ PINCTRL_PIN_GROUP(gpio19), -+ PINCTRL_PIN_GROUP(gpio20), -+ PINCTRL_PIN_GROUP(gpio21), -+ PINCTRL_PIN_GROUP(gpio22), -+ PINCTRL_PIN_GROUP(gpio23), -+ PINCTRL_PIN_GROUP(gpio24), -+ PINCTRL_PIN_GROUP(gpio25), -+ PINCTRL_PIN_GROUP(gpio26), -+ PINCTRL_PIN_GROUP(gpio27), -+ PINCTRL_PIN_GROUP(gpio28), -+ PINCTRL_PIN_GROUP(gpio29), -+ PINCTRL_PIN_GROUP(gpio30), -+ PINCTRL_PIN_GROUP(gpio31), -+ PINCTRL_PIN_GROUP(gpio33), -+ PINCTRL_PIN_GROUP(gpio34), -+ PINCTRL_PIN_GROUP(gpio35), -+ PINCTRL_PIN_GROUP(gpio36), -+ PINCTRL_PIN_GROUP(gpio37), -+ PINCTRL_PIN_GROUP(gpio38), -+ PINCTRL_PIN_GROUP(gpio39), -+ PINCTRL_PIN_GROUP(gpio40), -+ PINCTRL_PIN_GROUP(gpio41), -+ PINCTRL_PIN_GROUP(gpio42), -+ PINCTRL_PIN_GROUP(gpio43), -+ PINCTRL_PIN_GROUP(gpio44), -+ PINCTRL_PIN_GROUP(gpio45), -+ PINCTRL_PIN_GROUP(gpio46), -+ PINCTRL_PIN_GROUP(pcie_reset0), -+ PINCTRL_PIN_GROUP(pcie_reset1), -+ PINCTRL_PIN_GROUP(pcie_reset2), -+}; -+ -+static const char *const pon_groups[] = { "pon" }; -+static const char *const tod_1pps_groups[] = { "pon_tod_1pps", "gsw_tod_1pps" }; -+static const char *const sipo_groups[] = { "sipo", "sipo_rclk" }; -+static const char *const mdio_groups[] = { "mdio" }; -+static const char *const uart_groups[] = { "uart2", "uart2_cts_rts", "hsuart", -+ "hsuart_cts_rts", "uart4", -+ "uart5" }; -+static const char *const i2c_groups[] = { "i2c1" }; -+static const char *const jtag_groups[] = { "jtag_udi", "jtag_dfd" }; -+static const char *const pcm_groups[] = { "pcm1", "pcm2" }; -+static const char *const spi_groups[] = { "spi_quad", "spi_cs1" }; -+static const char *const pcm_spi_groups[] = { "pcm_spi", "pcm_spi_int", -+ "pcm_spi_rst", "pcm_spi_cs1", -+ "pcm_spi_cs2_p156", -+ "pcm_spi_cs2_p128", -+ "pcm_spi_cs3", "pcm_spi_cs4" }; -+static const char *const i2s_groups[] = { "i2s" }; -+static const char *const emmc_groups[] = { "emmc" }; -+static const char *const pnand_groups[] = { "pnand" }; -+static const char *const pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1", -+ "pcie_reset2" }; -+static const char *const pwm_groups[] = { "gpio0", "gpio1", -+ "gpio2", "gpio3", -+ "gpio4", "gpio5", -+ "gpio6", "gpio7", -+ "gpio8", "gpio9", -+ "gpio10", "gpio11", -+ "gpio12", "gpio13", -+ "gpio14", "gpio15", -+ "gpio16", "gpio17", -+ "gpio18", "gpio19", -+ "gpio20", "gpio21", -+ "gpio22", "gpio23", -+ "gpio24", "gpio25", -+ "gpio26", "gpio27", -+ "gpio28", "gpio29", -+ "gpio30", "gpio31", -+ "gpio36", "gpio37", -+ "gpio38", "gpio39", -+ "gpio40", "gpio41", -+ "gpio42", "gpio43", -+ "gpio44", "gpio45", -+ "gpio46", "gpio47" }; -+static const char *const phy1_led0_groups[] = { "gpio33", "gpio34", -+ "gpio35", "gpio42" }; -+static const char *const phy2_led0_groups[] = { "gpio33", "gpio34", -+ "gpio35", "gpio42" }; -+static const char *const phy3_led0_groups[] = { "gpio33", "gpio34", -+ "gpio35", "gpio42" }; -+static const char *const phy4_led0_groups[] = { "gpio33", "gpio34", -+ "gpio35", "gpio42" }; -+static const char *const phy1_led1_groups[] = { "gpio43", "gpio44", -+ "gpio45", "gpio46" }; -+static const char *const phy2_led1_groups[] = { "gpio43", "gpio44", -+ "gpio45", "gpio46" }; -+static const char *const phy3_led1_groups[] = { "gpio43", "gpio44", -+ "gpio45", "gpio46" }; -+static const char *const phy4_led1_groups[] = { "gpio43", "gpio44", -+ "gpio45", "gpio46" }; -+ -+static const struct airoha_pinctrl_func_group pon_func_group[] = { -+ { -+ .name = "pon", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_PON_MODE_MASK, -+ GPIO_PON_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group tod_1pps_func_group[] = { -+ { -+ .name = "pon_tod_1pps", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ PON_TOD_1PPS_MODE_MASK, -+ PON_TOD_1PPS_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gsw_tod_1pps", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GSW_TOD_1PPS_MODE_MASK, -+ GSW_TOD_1PPS_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group sipo_func_group[] = { -+ { -+ .name = "sipo", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK, -+ GPIO_SIPO_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "sipo_rclk", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK, -+ GPIO_SIPO_MODE_MASK | SIPO_RCLK_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group mdio_func_group[] = { -+ { -+ .name = "mdio", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_SGMII_MDIO_MODE_MASK, -+ GPIO_SGMII_MDIO_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_MDC_IO_MASTER_MODE_MODE, -+ GPIO_MDC_IO_MASTER_MODE_MODE -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group uart_func_group[] = { -+ { -+ .name = "uart2", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_UART2_MODE_MASK, -+ GPIO_UART2_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "uart2_cts_rts", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK, -+ GPIO_UART2_MODE_MASK | GPIO_UART2_CTS_RTS_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "hsuart", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK, -+ GPIO_HSUART_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+ { -+ .name = "hsuart_cts_rts", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK, -+ GPIO_HSUART_MODE_MASK | GPIO_HSUART_CTS_RTS_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "uart4", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_UART4_MODE_MASK, -+ GPIO_UART4_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "uart5", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_UART5_MODE_MASK, -+ GPIO_UART5_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group i2c_func_group[] = { -+ { -+ .name = "i2c1", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_2ND_I2C_MODE_MASK, -+ GPIO_2ND_I2C_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group jtag_func_group[] = { -+ { -+ .name = "jtag_udi", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_NPU_UART_EN, -+ JTAG_UDI_EN_MASK, -+ JTAG_UDI_EN_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "jtag_dfd", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_NPU_UART_EN, -+ JTAG_DFD_EN_MASK, -+ JTAG_DFD_EN_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group pcm_func_group[] = { -+ { -+ .name = "pcm1", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM1_MODE_MASK, -+ GPIO_PCM1_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm2", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM2_MODE_MASK, -+ GPIO_PCM2_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group spi_func_group[] = { -+ { -+ .name = "spi_quad", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_SPI_QUAD_MODE_MASK, -+ GPIO_SPI_QUAD_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "spi_cs1", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_SPI_CS1_MODE_MASK, -+ GPIO_SPI_CS1_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "spi_cs2", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_SPI_CS2_MODE_MASK, -+ GPIO_SPI_CS2_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "spi_cs3", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_SPI_CS3_MODE_MASK, -+ GPIO_SPI_CS3_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "spi_cs4", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_SPI_CS4_MODE_MASK, -+ GPIO_SPI_CS4_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group pcm_spi_func_group[] = { -+ { -+ .name = "pcm_spi", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_MODE_MASK, -+ GPIO_PCM_SPI_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_int", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_INT_MODE_MASK, -+ GPIO_PCM_INT_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_rst", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_RESET_MODE_MASK, -+ GPIO_PCM_RESET_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs1", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS1_MODE_MASK, -+ GPIO_PCM_SPI_CS1_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs2_p128", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS2_MODE_P128_MASK, -+ GPIO_PCM_SPI_CS2_MODE_P128_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs2_p156", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS2_MODE_P156_MASK, -+ GPIO_PCM_SPI_CS2_MODE_P156_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs3", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS3_MODE_MASK, -+ GPIO_PCM_SPI_CS3_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs4", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS4_MODE_MASK, -+ GPIO_PCM_SPI_CS4_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group i2s_func_group[] = { -+ { -+ .name = "i2s", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_I2S_MODE_MASK, -+ GPIO_I2S_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group emmc_func_group[] = { -+ { -+ .name = "emmc", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_EMMC_MODE_MASK, -+ GPIO_EMMC_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group pnand_func_group[] = { -+ { -+ .name = "pnand", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_PARALLEL_NAND_MODE_MASK, -+ GPIO_PARALLEL_NAND_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group pcie_reset_func_group[] = { -+ { -+ .name = "pcie_reset0", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_PCIE_RESET0_MASK, -+ GPIO_PCIE_RESET0_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcie_reset1", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_PCIE_RESET1_MASK, -+ GPIO_PCIE_RESET1_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcie_reset2", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_PCIE_RESET2_MASK, -+ GPIO_PCIE_RESET2_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+/* PWM */ -+static const struct airoha_pinctrl_func_group pwm_func_group[] = { -+ { -+ .name = "gpio0", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO0_FLASH_MODE_CFG, -+ GPIO0_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio1", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO1_FLASH_MODE_CFG, -+ GPIO1_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio2", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO2_FLASH_MODE_CFG, -+ GPIO2_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio3", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO3_FLASH_MODE_CFG, -+ GPIO3_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio4", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO4_FLASH_MODE_CFG, -+ GPIO4_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio5", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO5_FLASH_MODE_CFG, -+ GPIO5_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio6", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO6_FLASH_MODE_CFG, -+ GPIO6_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio7", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO7_FLASH_MODE_CFG, -+ GPIO7_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio8", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO8_FLASH_MODE_CFG, -+ GPIO8_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio9", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO9_FLASH_MODE_CFG, -+ GPIO9_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio10", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO10_FLASH_MODE_CFG, -+ GPIO10_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio11", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO11_FLASH_MODE_CFG, -+ GPIO11_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio12", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO12_FLASH_MODE_CFG, -+ GPIO12_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio13", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO13_FLASH_MODE_CFG, -+ GPIO13_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio14", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO14_FLASH_MODE_CFG, -+ GPIO14_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio15", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_MUX, -+ REG_GPIO_FLASH_MODE_CFG, -+ GPIO15_FLASH_MODE_CFG, -+ GPIO15_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio16", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO16_FLASH_MODE_CFG, -+ GPIO16_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio17", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO17_FLASH_MODE_CFG, -+ GPIO17_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio18", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO18_FLASH_MODE_CFG, -+ GPIO18_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio19", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO19_FLASH_MODE_CFG, -+ GPIO19_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio20", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO20_FLASH_MODE_CFG, -+ GPIO20_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio21", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO21_FLASH_MODE_CFG, -+ GPIO21_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio22", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO22_FLASH_MODE_CFG, -+ GPIO22_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio23", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO23_FLASH_MODE_CFG, -+ GPIO23_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio24", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO24_FLASH_MODE_CFG, -+ GPIO24_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio25", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO25_FLASH_MODE_CFG, -+ GPIO25_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio26", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO26_FLASH_MODE_CFG, -+ GPIO26_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio27", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO27_FLASH_MODE_CFG, -+ GPIO27_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio28", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO28_FLASH_MODE_CFG, -+ GPIO28_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio29", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO29_FLASH_MODE_CFG, -+ GPIO29_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio30", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO30_FLASH_MODE_CFG, -+ GPIO30_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio31", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO31_FLASH_MODE_CFG, -+ GPIO31_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio36", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO36_FLASH_MODE_CFG, -+ GPIO36_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio37", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO37_FLASH_MODE_CFG, -+ GPIO37_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio38", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO38_FLASH_MODE_CFG, -+ GPIO38_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio39", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO39_FLASH_MODE_CFG, -+ GPIO39_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio40", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO40_FLASH_MODE_CFG, -+ GPIO40_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio41", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO41_FLASH_MODE_CFG, -+ GPIO41_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio42", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO42_FLASH_MODE_CFG, -+ GPIO42_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio43", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO43_FLASH_MODE_CFG, -+ GPIO43_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio44", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO44_FLASH_MODE_CFG, -+ GPIO44_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio45", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO45_FLASH_MODE_CFG, -+ GPIO45_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio46", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO46_FLASH_MODE_CFG, -+ GPIO46_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "gpio47", -+ .regmap[0] = { -+ AIROHA_FUNC_PWM_EXT_MUX, -+ REG_GPIO_FLASH_MODE_CFG_EXT, -+ GPIO47_FLASH_MODE_CFG, -+ GPIO47_FLASH_MODE_CFG -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = { -+ { -+ .name = "gpio33", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED0_MODE_MASK, -+ GPIO_LAN0_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio34", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED0_MODE_MASK, -+ GPIO_LAN1_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio35", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED0_MODE_MASK, -+ GPIO_LAN2_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio42", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = { -+ { -+ .name = "gpio33", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED0_MODE_MASK, -+ GPIO_LAN0_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio34", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED0_MODE_MASK, -+ GPIO_LAN1_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio35", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED0_MODE_MASK, -+ GPIO_LAN2_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio42", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = { -+ { -+ .name = "gpio33", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED0_MODE_MASK, -+ GPIO_LAN0_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio34", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED0_MODE_MASK, -+ GPIO_LAN1_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio35", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED0_MODE_MASK, -+ GPIO_LAN2_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio42", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = { -+ { -+ .name = "gpio33", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED0_MODE_MASK, -+ GPIO_LAN0_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio34", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED0_MODE_MASK, -+ GPIO_LAN1_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio35", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED0_MODE_MASK, -+ GPIO_LAN2_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio42", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED0_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = { -+ { -+ .name = "gpio43", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED1_MODE_MASK, -+ GPIO_LAN0_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio44", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED1_MODE_MASK, -+ GPIO_LAN1_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio45", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED1_MODE_MASK, -+ GPIO_LAN2_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio46", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY1_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = { -+ { -+ .name = "gpio43", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED1_MODE_MASK, -+ GPIO_LAN0_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio44", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED1_MODE_MASK, -+ GPIO_LAN1_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio45", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED1_MODE_MASK, -+ GPIO_LAN2_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio46", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY2_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = { -+ { -+ .name = "gpio43", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED1_MODE_MASK, -+ GPIO_LAN0_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio44", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED1_MODE_MASK, -+ GPIO_LAN1_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio45", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED1_MODE_MASK, -+ GPIO_LAN2_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio46", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY3_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = { -+ { -+ .name = "gpio43", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN0_LED1_MODE_MASK, -+ GPIO_LAN0_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio44", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN1_LED1_MODE_MASK, -+ GPIO_LAN1_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio45", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN2_LED1_MODE_MASK, -+ GPIO_LAN2_LED1_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, { -+ .name = "gpio46", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_2ND_I2C_MODE, -+ GPIO_LAN3_LED0_MODE_MASK, -+ GPIO_LAN3_LED0_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_LAN_LED1_MAPPING, -+ LAN4_LED_MAPPING_MASK, -+ LAN4_PHY4_LED_MAP -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ -+static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = { -+ PINCTRL_FUNC_DESC(pon), -+ PINCTRL_FUNC_DESC(tod_1pps), -+ PINCTRL_FUNC_DESC(sipo), -+ PINCTRL_FUNC_DESC(mdio), -+ PINCTRL_FUNC_DESC(uart), -+ PINCTRL_FUNC_DESC(i2c), -+ PINCTRL_FUNC_DESC(jtag), -+ PINCTRL_FUNC_DESC(pcm), -+ PINCTRL_FUNC_DESC(spi), -+ PINCTRL_FUNC_DESC(pcm_spi), -+ PINCTRL_FUNC_DESC(i2s), -+ PINCTRL_FUNC_DESC(emmc), -+ PINCTRL_FUNC_DESC(pnand), -+ PINCTRL_FUNC_DESC(pcie_reset), -+ PINCTRL_FUNC_DESC(pwm), -+ PINCTRL_FUNC_DESC(phy1_led0), -+ PINCTRL_FUNC_DESC(phy2_led0), -+ PINCTRL_FUNC_DESC(phy3_led0), -+ PINCTRL_FUNC_DESC(phy4_led0), -+ PINCTRL_FUNC_DESC(phy1_led1), -+ PINCTRL_FUNC_DESC(phy2_led1), -+ PINCTRL_FUNC_DESC(phy3_led1), -+ PINCTRL_FUNC_DESC(phy4_led1), -+}; -+ -+static const struct airoha_pinctrl_conf airoha_pinctrl_pullup_conf[] = { -+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), -+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), -+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_PU, I2C_SDA_PU_MASK), -+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_PU, I2C_SCL_PU_MASK), -+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_PU, SPI_CS0_PU_MASK), -+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_PU, SPI_CLK_PU_MASK), -+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK), -+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_PU, SPI_MISO_PU_MASK), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(0)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(1)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(2)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(3)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(4)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(5)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(6)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(7)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(8)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(9)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(10)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(11)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(12)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(13)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(14)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(15)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(16)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(17)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(18)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(18)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(20)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_L_PU, BIT(21)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_L_PU, BIT(22)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_L_PU, BIT(23)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_L_PU, BIT(24)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_L_PU, BIT(25)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_L_PU, BIT(26)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_L_PU, BIT(27)), -+ PINCTRL_CONF_DESC(41, REG_GPIO_L_PU, BIT(28)), -+ PINCTRL_CONF_DESC(42, REG_GPIO_L_PU, BIT(29)), -+ PINCTRL_CONF_DESC(43, REG_GPIO_L_PU, BIT(30)), -+ PINCTRL_CONF_DESC(44, REG_GPIO_L_PU, BIT(31)), -+ PINCTRL_CONF_DESC(45, REG_GPIO_H_PU, BIT(0)), -+ PINCTRL_CONF_DESC(46, REG_GPIO_H_PU, BIT(1)), -+ PINCTRL_CONF_DESC(47, REG_GPIO_H_PU, BIT(2)), -+ PINCTRL_CONF_DESC(48, REG_GPIO_H_PU, BIT(3)), -+ PINCTRL_CONF_DESC(49, REG_GPIO_H_PU, BIT(4)), -+ PINCTRL_CONF_DESC(50, REG_GPIO_H_PU, BIT(5)), -+ PINCTRL_CONF_DESC(51, REG_GPIO_H_PU, BIT(6)), -+ PINCTRL_CONF_DESC(52, REG_GPIO_H_PU, BIT(7)), -+ PINCTRL_CONF_DESC(53, REG_GPIO_H_PU, BIT(8)), -+ PINCTRL_CONF_DESC(54, REG_GPIO_H_PU, BIT(9)), -+ PINCTRL_CONF_DESC(55, REG_GPIO_H_PU, BIT(10)), -+ PINCTRL_CONF_DESC(56, REG_GPIO_H_PU, BIT(11)), -+ PINCTRL_CONF_DESC(57, REG_GPIO_H_PU, BIT(12)), -+ PINCTRL_CONF_DESC(58, REG_GPIO_H_PU, BIT(13)), -+ PINCTRL_CONF_DESC(59, REG_GPIO_H_PU, BIT(14)), -+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK), -+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK), -+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK), -+}; -+ -+static const struct airoha_pinctrl_conf airoha_pinctrl_pulldown_conf[] = { -+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), -+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), -+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_PD, I2C_SDA_PD_MASK), -+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_PD, I2C_SCL_PD_MASK), -+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_PD, SPI_CS0_PD_MASK), -+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_PD, SPI_CLK_PD_MASK), -+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK), -+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_PD, SPI_MISO_PD_MASK), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(0)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(1)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(2)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(3)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(4)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(5)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(6)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(7)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(8)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(9)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(10)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(11)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(12)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(13)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(14)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(15)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(16)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(17)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(18)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(18)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(20)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_L_PD, BIT(21)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_L_PD, BIT(22)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_L_PD, BIT(23)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_L_PD, BIT(24)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_L_PD, BIT(25)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_L_PD, BIT(26)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_L_PD, BIT(27)), -+ PINCTRL_CONF_DESC(41, REG_GPIO_L_PD, BIT(28)), -+ PINCTRL_CONF_DESC(42, REG_GPIO_L_PD, BIT(29)), -+ PINCTRL_CONF_DESC(43, REG_GPIO_L_PD, BIT(30)), -+ PINCTRL_CONF_DESC(44, REG_GPIO_L_PD, BIT(31)), -+ PINCTRL_CONF_DESC(45, REG_GPIO_H_PD, BIT(0)), -+ PINCTRL_CONF_DESC(46, REG_GPIO_H_PD, BIT(1)), -+ PINCTRL_CONF_DESC(47, REG_GPIO_H_PD, BIT(2)), -+ PINCTRL_CONF_DESC(48, REG_GPIO_H_PD, BIT(3)), -+ PINCTRL_CONF_DESC(49, REG_GPIO_H_PD, BIT(4)), -+ PINCTRL_CONF_DESC(50, REG_GPIO_H_PD, BIT(5)), -+ PINCTRL_CONF_DESC(51, REG_GPIO_H_PD, BIT(6)), -+ PINCTRL_CONF_DESC(52, REG_GPIO_H_PD, BIT(7)), -+ PINCTRL_CONF_DESC(53, REG_GPIO_H_PD, BIT(8)), -+ PINCTRL_CONF_DESC(54, REG_GPIO_H_PD, BIT(9)), -+ PINCTRL_CONF_DESC(55, REG_GPIO_H_PD, BIT(10)), -+ PINCTRL_CONF_DESC(56, REG_GPIO_H_PD, BIT(11)), -+ PINCTRL_CONF_DESC(57, REG_GPIO_H_PD, BIT(12)), -+ PINCTRL_CONF_DESC(58, REG_GPIO_H_PD, BIT(13)), -+ PINCTRL_CONF_DESC(59, REG_GPIO_H_PD, BIT(14)), -+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK), -+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK), -+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK), -+}; -+ -+static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e2_conf[] = { -+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), -+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), -+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_E2, I2C_SDA_E2_MASK), -+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_E2, I2C_SCL_E2_MASK), -+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_E2, SPI_CS0_E2_MASK), -+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_E2, SPI_CLK_E2_MASK), -+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK), -+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_E2, SPI_MISO_E2_MASK), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(0)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(1)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(2)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(3)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(4)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(5)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(6)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(7)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(8)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(9)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(10)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(11)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(12)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(13)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(14)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(15)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(16)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(17)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(18)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(18)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(20)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_L_E2, BIT(21)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_L_E2, BIT(22)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_L_E2, BIT(23)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_L_E2, BIT(24)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_L_E2, BIT(25)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_L_E2, BIT(26)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_L_E2, BIT(27)), -+ PINCTRL_CONF_DESC(41, REG_GPIO_L_E2, BIT(28)), -+ PINCTRL_CONF_DESC(42, REG_GPIO_L_E2, BIT(29)), -+ PINCTRL_CONF_DESC(43, REG_GPIO_L_E2, BIT(30)), -+ PINCTRL_CONF_DESC(44, REG_GPIO_L_E2, BIT(31)), -+ PINCTRL_CONF_DESC(45, REG_GPIO_H_E2, BIT(0)), -+ PINCTRL_CONF_DESC(46, REG_GPIO_H_E2, BIT(1)), -+ PINCTRL_CONF_DESC(47, REG_GPIO_H_E2, BIT(2)), -+ PINCTRL_CONF_DESC(48, REG_GPIO_H_E2, BIT(3)), -+ PINCTRL_CONF_DESC(49, REG_GPIO_H_E2, BIT(4)), -+ PINCTRL_CONF_DESC(50, REG_GPIO_H_E2, BIT(5)), -+ PINCTRL_CONF_DESC(51, REG_GPIO_H_E2, BIT(6)), -+ PINCTRL_CONF_DESC(52, REG_GPIO_H_E2, BIT(7)), -+ PINCTRL_CONF_DESC(53, REG_GPIO_H_E2, BIT(8)), -+ PINCTRL_CONF_DESC(54, REG_GPIO_H_E2, BIT(9)), -+ PINCTRL_CONF_DESC(55, REG_GPIO_H_E2, BIT(10)), -+ PINCTRL_CONF_DESC(56, REG_GPIO_H_E2, BIT(11)), -+ PINCTRL_CONF_DESC(57, REG_GPIO_H_E2, BIT(12)), -+ PINCTRL_CONF_DESC(58, REG_GPIO_H_E2, BIT(13)), -+ PINCTRL_CONF_DESC(59, REG_GPIO_H_E2, BIT(14)), -+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK), -+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK), -+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK), -+}; -+ -+static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e4_conf[] = { -+ PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), -+ PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), -+ PINCTRL_CONF_DESC(2, REG_I2C_SDA_E4, I2C_SDA_E4_MASK), -+ PINCTRL_CONF_DESC(3, REG_I2C_SDA_E4, I2C_SCL_E4_MASK), -+ PINCTRL_CONF_DESC(4, REG_I2C_SDA_E4, SPI_CS0_E4_MASK), -+ PINCTRL_CONF_DESC(5, REG_I2C_SDA_E4, SPI_CLK_E4_MASK), -+ PINCTRL_CONF_DESC(6, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK), -+ PINCTRL_CONF_DESC(7, REG_I2C_SDA_E4, SPI_MISO_E4_MASK), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(0)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(1)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(2)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(3)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(4)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(5)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(6)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(7)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(8)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(9)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(10)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(11)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(12)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(13)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(14)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(15)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(16)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(17)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(18)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(18)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(20)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_L_E4, BIT(21)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_L_E4, BIT(22)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_L_E4, BIT(23)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_L_E4, BIT(24)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_L_E4, BIT(25)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_L_E4, BIT(26)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_L_E4, BIT(27)), -+ PINCTRL_CONF_DESC(41, REG_GPIO_L_E4, BIT(28)), -+ PINCTRL_CONF_DESC(42, REG_GPIO_L_E4, BIT(29)), -+ PINCTRL_CONF_DESC(43, REG_GPIO_L_E4, BIT(30)), -+ PINCTRL_CONF_DESC(44, REG_GPIO_L_E4, BIT(31)), -+ PINCTRL_CONF_DESC(45, REG_GPIO_H_E4, BIT(0)), -+ PINCTRL_CONF_DESC(46, REG_GPIO_H_E4, BIT(1)), -+ PINCTRL_CONF_DESC(47, REG_GPIO_H_E4, BIT(2)), -+ PINCTRL_CONF_DESC(48, REG_GPIO_H_E4, BIT(3)), -+ PINCTRL_CONF_DESC(49, REG_GPIO_H_E4, BIT(4)), -+ PINCTRL_CONF_DESC(50, REG_GPIO_H_E4, BIT(5)), -+ PINCTRL_CONF_DESC(51, REG_GPIO_H_E4, BIT(6)), -+ PINCTRL_CONF_DESC(52, REG_GPIO_H_E4, BIT(7)), -+ PINCTRL_CONF_DESC(53, REG_GPIO_H_E4, BIT(8)), -+ PINCTRL_CONF_DESC(54, REG_GPIO_H_E4, BIT(9)), -+ PINCTRL_CONF_DESC(55, REG_GPIO_H_E4, BIT(10)), -+ PINCTRL_CONF_DESC(56, REG_GPIO_H_E4, BIT(11)), -+ PINCTRL_CONF_DESC(57, REG_GPIO_H_E4, BIT(12)), -+ PINCTRL_CONF_DESC(58, REG_GPIO_H_E4, BIT(13)), -+ PINCTRL_CONF_DESC(59, REG_GPIO_H_E4, BIT(14)), -+ PINCTRL_CONF_DESC(61, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK), -+ PINCTRL_CONF_DESC(62, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK), -+ PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK), -+}; -+ -+static const struct airoha_pinctrl_conf airoha_pinctrl_pcie_rst_od_conf[] = { -+ PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), -+ PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), -+ PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK), -+}; -+ -+static int airoha_convert_pin_to_reg_offset(struct pinctrl_dev *pctrl_dev, -+ struct pinctrl_gpio_range *range, -+ int pin) -+{ -+ if (!range) -+ range = pinctrl_find_gpio_range_from_pin_nolock(pctrl_dev, -+ pin); -+ if (!range) -+ return -EINVAL; -+ -+ return pin - range->pin_base; -+} -+ -+/* gpio callbacks */ -+static void airoha_gpio_set(struct gpio_chip *chip, unsigned int gpio, -+ int value) -+{ -+ struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip); -+ u32 offset = gpio % AIROHA_PIN_BANK_SIZE; -+ u8 index = gpio / AIROHA_PIN_BANK_SIZE; -+ -+ regmap_update_bits(pinctrl->regmap, pinctrl->gpiochip.data[index], -+ BIT(offset), value ? BIT(offset) : 0); -+} -+ -+static int airoha_gpio_get(struct gpio_chip *chip, unsigned int gpio) -+{ -+ struct airoha_pinctrl *pinctrl = gpiochip_get_data(chip); -+ u32 val, pin = gpio % AIROHA_PIN_BANK_SIZE; -+ u8 index = gpio / AIROHA_PIN_BANK_SIZE; -+ int err; -+ -+ err = regmap_read(pinctrl->regmap, -+ pinctrl->gpiochip.data[index], &val); -+ -+ return err ? err : !!(val & BIT(pin)); -+} -+ -+static int airoha_gpio_direction_output(struct gpio_chip *chip, -+ unsigned int gpio, int value) -+{ -+ int err; -+ -+ err = pinctrl_gpio_direction_output(chip, gpio); -+ if (err) -+ return err; -+ -+ airoha_gpio_set(chip, gpio, value); -+ -+ return 0; -+} -+ -+/* irq callbacks */ -+static void airoha_irq_unmask(struct irq_data *data) -+{ -+ u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_PIN; -+ u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_PIN; -+ u32 mask = GENMASK(2 * offset + 1, 2 * offset); -+ struct airoha_pinctrl_gpiochip *gpiochip; -+ struct airoha_pinctrl *pinctrl; -+ u32 val = BIT(2 * offset); -+ -+ gpiochip = irq_data_get_irq_chip_data(data); -+ if (WARN_ON_ONCE(data->hwirq >= ARRAY_SIZE(gpiochip->irq_type))) -+ return; -+ -+ pinctrl = container_of(gpiochip, struct airoha_pinctrl, gpiochip); -+ switch (gpiochip->irq_type[data->hwirq]) { -+ case IRQ_TYPE_LEVEL_LOW: -+ val = val << 1; -+ fallthrough; -+ case IRQ_TYPE_LEVEL_HIGH: -+ regmap_update_bits(pinctrl->regmap, gpiochip->level[index], -+ mask, val); -+ break; -+ case IRQ_TYPE_EDGE_FALLING: -+ val = val << 1; -+ fallthrough; -+ case IRQ_TYPE_EDGE_RISING: -+ regmap_update_bits(pinctrl->regmap, gpiochip->edge[index], -+ mask, val); -+ break; -+ case IRQ_TYPE_EDGE_BOTH: -+ regmap_set_bits(pinctrl->regmap, gpiochip->edge[index], mask); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void airoha_irq_mask(struct irq_data *data) -+{ -+ u8 offset = data->hwirq % AIROHA_REG_GPIOCTRL_NUM_PIN; -+ u8 index = data->hwirq / AIROHA_REG_GPIOCTRL_NUM_PIN; -+ u32 mask = GENMASK(2 * offset + 1, 2 * offset); -+ struct airoha_pinctrl_gpiochip *gpiochip; -+ struct airoha_pinctrl *pinctrl; -+ -+ gpiochip = irq_data_get_irq_chip_data(data); -+ pinctrl = container_of(gpiochip, struct airoha_pinctrl, gpiochip); -+ -+ regmap_clear_bits(pinctrl->regmap, gpiochip->level[index], mask); -+ regmap_clear_bits(pinctrl->regmap, gpiochip->edge[index], mask); -+} -+ -+static int airoha_irq_type(struct irq_data *data, unsigned int type) -+{ -+ struct airoha_pinctrl_gpiochip *gpiochip; -+ -+ gpiochip = irq_data_get_irq_chip_data(data); -+ if (data->hwirq >= ARRAY_SIZE(gpiochip->irq_type)) -+ return -EINVAL; -+ -+ if (type == IRQ_TYPE_PROBE) { -+ if (gpiochip->irq_type[data->hwirq]) -+ return 0; -+ -+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; -+ } -+ gpiochip->irq_type[data->hwirq] = type & IRQ_TYPE_SENSE_MASK; -+ -+ return 0; -+} -+ -+static irqreturn_t airoha_irq_handler(int irq, void *data) -+{ -+ struct airoha_pinctrl *pinctrl = data; -+ bool handled = false; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(irq_status_regs); i++) { -+ struct gpio_irq_chip *girq = &pinctrl->gpiochip.chip.irq; -+ u32 status; -+ int irq; -+ -+ if (regmap_read(pinctrl->regmap, pinctrl->gpiochip.status[i], -+ &status)) -+ continue; -+ -+ for_each_set_bit(irq, (unsigned long *)&status, -+ AIROHA_PIN_BANK_SIZE) { -+ u32 offset = irq + i * AIROHA_PIN_BANK_SIZE; -+ -+ generic_handle_irq(irq_find_mapping(girq->domain, -+ offset)); -+ regmap_write(pinctrl->regmap, -+ pinctrl->gpiochip.status[i], BIT(irq)); -+ } -+ handled |= !!status; -+ } -+ -+ return handled ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+static const struct irq_chip airoha_gpio_irq_chip = { -+ .name = "airoha-gpio-irq", -+ .irq_unmask = airoha_irq_unmask, -+ .irq_mask = airoha_irq_mask, -+ .irq_mask_ack = airoha_irq_mask, -+ .irq_set_type = airoha_irq_type, -+ .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE, -+}; -+ -+static int airoha_pinctrl_add_gpiochip(struct airoha_pinctrl *pinctrl, -+ struct platform_device *pdev) -+{ -+ struct airoha_pinctrl_gpiochip *chip = &pinctrl->gpiochip; -+ struct gpio_chip *gc = &chip->chip; -+ struct gpio_irq_chip *girq = &gc->irq; -+ struct device *dev = &pdev->dev; -+ int irq, err; -+ -+ chip->data = gpio_data_regs; -+ chip->dir = gpio_dir_regs; -+ chip->out = gpio_out_regs; -+ chip->status = irq_status_regs; -+ chip->level = irq_level_regs; -+ chip->edge = irq_edge_regs; -+ -+ gc->parent = dev; -+ gc->label = dev_name(dev); -+ gc->request = gpiochip_generic_request; -+ gc->free = gpiochip_generic_free; -+ gc->direction_input = pinctrl_gpio_direction_input; -+ gc->direction_output = airoha_gpio_direction_output; -+ gc->set = airoha_gpio_set; -+ gc->get = airoha_gpio_get; -+ gc->base = -1; -+ gc->ngpio = AIROHA_NUM_PINS; -+ -+ girq->default_type = IRQ_TYPE_NONE; -+ girq->handler = handle_simple_irq; -+ gpio_irq_chip_set_chip(girq, &airoha_gpio_irq_chip); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+ -+ err = devm_request_irq(dev, irq, airoha_irq_handler, IRQF_SHARED, -+ dev_name(dev), pinctrl); -+ if (err) { -+ dev_err(dev, "error requesting irq %d: %d\n", irq, err); -+ return err; -+ } -+ -+ return devm_gpiochip_add_data(dev, gc, pinctrl); -+} -+ -+/* pinmux callbacks */ -+static int airoha_pinmux_set_mux(struct pinctrl_dev *pctrl_dev, -+ unsigned int selector, -+ unsigned int group) -+{ -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); -+ const struct airoha_pinctrl_func *func; -+ struct function_desc *desc; -+ struct group_desc *grp; -+ int i; -+ -+ desc = pinmux_generic_get_function(pctrl_dev, selector); -+ if (!desc) -+ return -EINVAL; -+ -+ grp = pinctrl_generic_get_group(pctrl_dev, group); -+ if (!grp) -+ return -EINVAL; -+ -+ dev_dbg(pctrl_dev->dev, "enable function %s group %s\n", -+ desc->func.name, grp->grp.name); -+ -+ func = desc->data; -+ for (i = 0; i < func->group_size; i++) { -+ const struct airoha_pinctrl_func_group *group; -+ int j; -+ -+ group = &func->groups[i]; -+ if (strcmp(group->name, grp->grp.name)) -+ continue; -+ -+ for (j = 0; j < group->regmap_size; j++) { -+ switch (group->regmap[j].mux) { -+ case AIROHA_FUNC_PWM_EXT_MUX: -+ case AIROHA_FUNC_PWM_MUX: -+ regmap_update_bits(pinctrl->regmap, -+ group->regmap[j].offset, -+ group->regmap[j].mask, -+ group->regmap[j].val); -+ break; -+ default: -+ regmap_update_bits(pinctrl->chip_scu, -+ group->regmap[j].offset, -+ group->regmap[j].mask, -+ group->regmap[j].val); -+ break; -+ } -+ } -+ return 0; -+ } -+ -+ return -EINVAL; -+} -+ -+static int airoha_pinmux_set_direction(struct pinctrl_dev *pctrl_dev, -+ struct pinctrl_gpio_range *range, -+ unsigned int p, bool input) -+{ -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); -+ u32 mask, index; -+ int err, pin; -+ -+ pin = airoha_convert_pin_to_reg_offset(pctrl_dev, range, p); -+ if (pin < 0) -+ return pin; -+ -+ /* set output enable */ -+ mask = BIT(pin % AIROHA_PIN_BANK_SIZE); -+ index = pin / AIROHA_PIN_BANK_SIZE; -+ err = regmap_update_bits(pinctrl->regmap, pinctrl->gpiochip.out[index], -+ mask, !input ? mask : 0); -+ if (err) -+ return err; -+ -+ /* set direction */ -+ mask = BIT(2 * (pin % AIROHA_REG_GPIOCTRL_NUM_PIN)); -+ index = pin / AIROHA_REG_GPIOCTRL_NUM_PIN; -+ return regmap_update_bits(pinctrl->regmap, -+ pinctrl->gpiochip.dir[index], mask, -+ !input ? mask : 0); -+} -+ -+static const struct pinmux_ops airoha_pmxops = { -+ .get_functions_count = pinmux_generic_get_function_count, -+ .get_function_name = pinmux_generic_get_function_name, -+ .get_function_groups = pinmux_generic_get_function_groups, -+ .gpio_set_direction = airoha_pinmux_set_direction, -+ .set_mux = airoha_pinmux_set_mux, -+ .strict = true, -+}; -+ -+/* pinconf callbacks */ -+static const struct airoha_pinctrl_reg * -+airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf, -+ int conf_size, int pin) -+{ -+ int i; -+ -+ for (i = 0; i < conf_size; i++) { -+ if (conf[i].pin == pin) -+ return &conf[i].reg; -+ } -+ -+ return NULL; -+} -+ -+static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl, -+ const struct airoha_pinctrl_conf *conf, -+ int conf_size, int pin, u32 *val) -+{ -+ const struct airoha_pinctrl_reg *reg; -+ -+ reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin); -+ if (!reg) -+ return -EINVAL; -+ -+ if (regmap_read(pinctrl->chip_scu, reg->offset, val)) -+ return -EINVAL; -+ -+ *val = (*val & reg->mask) >> __ffs(reg->mask); -+ -+ return 0; -+} -+ -+static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl, -+ const struct airoha_pinctrl_conf *conf, -+ int conf_size, int pin, u32 val) -+{ -+ const struct airoha_pinctrl_reg *reg = NULL; -+ -+ reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin); -+ if (!reg) -+ return -EINVAL; -+ -+ -+ if (regmap_update_bits(pinctrl->chip_scu, reg->offset, reg->mask, -+ val << __ffs(reg->mask))) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+#define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pullup_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_pullup_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pulldown_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pullup_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_pullup_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pulldown_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \ -+ (pin), (val)) -+#define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val) \ -+ airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \ -+ ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \ -+ (pin), (val)) -+ -+static int airoha_pinconf_get_direction(struct pinctrl_dev *pctrl_dev, u32 p) -+{ -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); -+ u32 val, mask; -+ int err, pin; -+ u8 index; -+ -+ pin = airoha_convert_pin_to_reg_offset(pctrl_dev, NULL, p); -+ if (pin < 0) -+ return pin; -+ -+ index = pin / AIROHA_REG_GPIOCTRL_NUM_PIN; -+ err = regmap_read(pinctrl->regmap, pinctrl->gpiochip.dir[index], &val); -+ if (err) -+ return err; -+ -+ mask = BIT(2 * (pin % AIROHA_REG_GPIOCTRL_NUM_PIN)); -+ return val & mask ? PIN_CONFIG_OUTPUT_ENABLE : PIN_CONFIG_INPUT_ENABLE; -+} -+ -+static int airoha_pinconf_get(struct pinctrl_dev *pctrl_dev, -+ unsigned int pin, unsigned long *config) -+{ -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); -+ enum pin_config_param param = pinconf_to_config_param(*config); -+ u32 arg; -+ -+ switch (param) { -+ case PIN_CONFIG_BIAS_PULL_DOWN: -+ case PIN_CONFIG_BIAS_DISABLE: -+ case PIN_CONFIG_BIAS_PULL_UP: { -+ u32 pull_up, pull_down; -+ -+ if (airoha_pinctrl_get_pullup_conf(pinctrl, pin, &pull_up) || -+ airoha_pinctrl_get_pulldown_conf(pinctrl, pin, &pull_down)) -+ return -EINVAL; -+ -+ if (param == PIN_CONFIG_BIAS_PULL_UP && -+ !(pull_up && !pull_down)) -+ return -EINVAL; -+ else if (param == PIN_CONFIG_BIAS_PULL_DOWN && -+ !(pull_down && !pull_up)) -+ return -EINVAL; -+ else if (pull_up || pull_down) -+ return -EINVAL; -+ -+ arg = 1; -+ break; -+ } -+ case PIN_CONFIG_DRIVE_STRENGTH: { -+ u32 e2, e4; -+ -+ if (airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, &e2) || -+ airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, &e4)) -+ return -EINVAL; -+ -+ arg = e4 << 1 | e2; -+ break; -+ } -+ case PIN_CONFIG_DRIVE_OPEN_DRAIN: -+ if (airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, &arg)) -+ return -EINVAL; -+ break; -+ case PIN_CONFIG_OUTPUT_ENABLE: -+ case PIN_CONFIG_INPUT_ENABLE: -+ arg = airoha_pinconf_get_direction(pctrl_dev, pin); -+ if (arg != param) -+ return -EINVAL; -+ -+ arg = 1; -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ *config = pinconf_to_config_packed(param, arg); -+ -+ return 0; -+} -+ -+static int airoha_pinconf_set_pin_value(struct pinctrl_dev *pctrl_dev, -+ unsigned int p, bool value) -+{ -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); -+ int pin; -+ -+ pin = airoha_convert_pin_to_reg_offset(pctrl_dev, NULL, p); -+ if (pin < 0) -+ return pin; -+ -+ airoha_gpio_set(&pinctrl->gpiochip.chip, pin, value); -+ -+ return 0; -+} -+ -+static int airoha_pinconf_set(struct pinctrl_dev *pctrl_dev, -+ unsigned int pin, unsigned long *configs, -+ unsigned int num_configs) -+{ -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); -+ int i; -+ -+ for (i = 0; i < num_configs; i++) { -+ u32 param = pinconf_to_config_param(configs[i]); -+ u32 arg = pinconf_to_config_argument(configs[i]); -+ -+ switch (param) { -+ case PIN_CONFIG_BIAS_DISABLE: -+ airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0); -+ airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0); -+ break; -+ case PIN_CONFIG_BIAS_PULL_UP: -+ airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0); -+ airoha_pinctrl_set_pullup_conf(pinctrl, pin, 1); -+ break; -+ case PIN_CONFIG_BIAS_PULL_DOWN: -+ airoha_pinctrl_set_pulldown_conf(pinctrl, pin, 1); -+ airoha_pinctrl_set_pullup_conf(pinctrl, pin, 0); -+ break; -+ case PIN_CONFIG_DRIVE_STRENGTH: { -+ u32 e2 = 0, e4 = 0; -+ -+ switch (arg) { -+ case MTK_DRIVE_2mA: -+ break; -+ case MTK_DRIVE_4mA: -+ e2 = 1; -+ break; -+ case MTK_DRIVE_6mA: -+ e4 = 1; -+ break; -+ case MTK_DRIVE_8mA: -+ e2 = 1; -+ e4 = 1; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, e2); -+ airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, e4); -+ break; -+ } -+ case PIN_CONFIG_DRIVE_OPEN_DRAIN: -+ airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, !!arg); -+ break; -+ case PIN_CONFIG_OUTPUT_ENABLE: -+ case PIN_CONFIG_INPUT_ENABLE: -+ case PIN_CONFIG_OUTPUT: { -+ bool input = param == PIN_CONFIG_INPUT_ENABLE; -+ int err; -+ -+ err = airoha_pinmux_set_direction(pctrl_dev, NULL, pin, -+ input); -+ if (err) -+ return err; -+ -+ if (param == PIN_CONFIG_OUTPUT) { -+ err = airoha_pinconf_set_pin_value(pctrl_dev, -+ pin, !!arg); -+ if (err) -+ return err; -+ } -+ break; -+ } -+ default: -+ return -EOPNOTSUPP; -+ } -+ } -+ -+ return 0; -+} -+ -+static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev, -+ unsigned int group, unsigned long *config) -+{ -+ u32 cur_config = 0; -+ int i; -+ -+ for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) { -+ if (airoha_pinconf_get(pctrl_dev, -+ airoha_pinctrl_groups[group].pins[i], -+ config)) -+ return -EOPNOTSUPP; -+ -+ if (i && cur_config != *config) -+ return -EOPNOTSUPP; -+ -+ cur_config = *config; -+ } -+ -+ return 0; -+} -+ -+static int airoha_pinconf_group_set(struct pinctrl_dev *pctrl_dev, -+ unsigned int group, unsigned long *configs, -+ unsigned int num_configs) -+{ -+ int i; -+ -+ for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) { -+ int err; -+ -+ err = airoha_pinconf_set(pctrl_dev, -+ airoha_pinctrl_groups[group].pins[i], -+ configs, num_configs); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static const struct pinconf_ops airoha_confops = { -+ .is_generic = true, -+ .pin_config_get = airoha_pinconf_get, -+ .pin_config_set = airoha_pinconf_set, -+ .pin_config_group_get = airoha_pinconf_group_get, -+ .pin_config_group_set = airoha_pinconf_group_set, -+ .pin_config_config_dbg_show = pinconf_generic_dump_config, -+}; -+ -+static const struct pinctrl_ops airoha_pctlops = { -+ .get_groups_count = pinctrl_generic_get_group_count, -+ .get_group_name = pinctrl_generic_get_group_name, -+ .get_group_pins = pinctrl_generic_get_group_pins, -+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all, -+ .dt_free_map = pinconf_generic_dt_free_map, -+}; -+ -+static struct pinctrl_desc airoha_pinctrl_desc = { -+ .name = KBUILD_MODNAME, -+ .owner = THIS_MODULE, -+ .pctlops = &airoha_pctlops, -+ .pmxops = &airoha_pmxops, -+ .confops = &airoha_confops, -+ .pins = airoha_pinctrl_pins, -+ .npins = ARRAY_SIZE(airoha_pinctrl_pins), -+}; -+ -+static int airoha_pinctrl_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct airoha_pinctrl *pinctrl; -+ struct regmap *map; -+ int err, i; -+ -+ pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL); -+ if (!pinctrl) -+ return -ENOMEM; -+ -+ pinctrl->regmap = device_node_to_regmap(dev->parent->of_node); -+ if (IS_ERR(pinctrl->regmap)) -+ return PTR_ERR(pinctrl->regmap); -+ -+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); -+ if (IS_ERR(map)) -+ return PTR_ERR(map); -+ -+ pinctrl->chip_scu = map; -+ -+ err = devm_pinctrl_register_and_init(dev, &airoha_pinctrl_desc, -+ pinctrl, &pinctrl->ctrl); -+ if (err) -+ return err; -+ -+ /* build pin groups */ -+ for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_groups); i++) { -+ const struct pingroup *grp = &airoha_pinctrl_groups[i]; -+ -+ err = pinctrl_generic_add_group(pinctrl->ctrl, grp->name, -+ grp->pins, grp->npins, -+ (void *)grp); -+ if (err < 0) { -+ dev_err(&pdev->dev, "Failed to register group %s\n", -+ grp->name); -+ return err; -+ } -+ } -+ -+ /* build functions */ -+ for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_funcs); i++) { -+ const struct airoha_pinctrl_func *func; -+ -+ func = &airoha_pinctrl_funcs[i]; -+ err = pinmux_generic_add_function(pinctrl->ctrl, -+ func->desc.func.name, -+ func->desc.func.groups, -+ func->desc.func.ngroups, -+ (void *)func); -+ if (err < 0) { -+ dev_err(dev, "Failed to register function %s\n", -+ func->desc.func.name); -+ return err; -+ } -+ } -+ -+ err = pinctrl_enable(pinctrl->ctrl); -+ if (err) -+ return err; -+ -+ /* build gpio-chip */ -+ return airoha_pinctrl_add_gpiochip(pinctrl, pdev); -+} -+ -+static const struct of_device_id airoha_pinctrl_of_match[] = { -+ { .compatible = "airoha,en7581-pinctrl" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, airoha_pinctrl_of_match); -+ -+static struct platform_driver airoha_pinctrl_driver = { -+ .probe = airoha_pinctrl_probe, -+ .driver = { -+ .name = "pinctrl-airoha", -+ .of_match_table = airoha_pinctrl_of_match, -+ }, -+}; -+module_platform_driver(airoha_pinctrl_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Lorenzo Bianconi "); -+MODULE_AUTHOR("Benjamin Larsson "); -+MODULE_AUTHOR("Markus Gothe "); -+MODULE_DESCRIPTION("Pinctrl driver for Airoha SoC"); diff --git a/target/linux/airoha/patches-6.12/034-02-v6.13-pinctrl-airoha-Use-unsigned-long-for-bit-search.patch b/target/linux/airoha/patches-6.12/034-02-v6.13-pinctrl-airoha-Use-unsigned-long-for-bit-search.patch deleted file mode 100644 index 62fae6aa38c..00000000000 --- a/target/linux/airoha/patches-6.12/034-02-v6.13-pinctrl-airoha-Use-unsigned-long-for-bit-search.patch +++ /dev/null @@ -1,61 +0,0 @@ -From ac6f0825e582f2216a582c9edf0cee7bfe347ba6 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Sun, 17 Nov 2024 03:45:38 -0800 -Subject: [PATCH] pinctrl: airoha: Use unsigned long for bit search - -Instead of risking alignment problems and causing (false positive) array -bound warnings when casting a u32 to (64-bit) unsigned long, just use a -native unsigned long for doing bit searches. Avoids warning with GCC 15's --Warray-bounds -fdiagnostics-details: - -In file included from ../include/linux/bitmap.h:11, - from ../include/linux/cpumask.h:12, - from ../arch/x86/include/asm/paravirt.h:21, - from ../arch/x86/include/asm/irqflags.h:80, - from ../include/linux/irqflags.h:18, - from ../include/linux/spinlock.h:59, - from ../include/linux/irq.h:14, - from ../include/linux/irqchip/chained_irq.h:10, - from ../include/linux/gpio/driver.h:8, - from ../drivers/pinctrl/mediatek/pinctrl-airoha.c:11: -In function 'find_next_bit', - inlined from 'airoha_irq_handler' at ../drivers/pinctrl/mediatek/pinctrl-airoha.c:2394:3: -../include/linux/find.h:65:23: error: array subscript 'long unsigned int[0]' is partly outside array bounds of 'u32[1]' {aka 'unsigned int[1]'} [-Werror=array-bounds=] - 65 | val = *addr & GENMASK(size - 1, offset); - | ^~~~~ -../drivers/pinctrl/mediatek/pinctrl-airoha.c: In function 'airoha_irq_handler': -../drivers/pinctrl/mediatek/pinctrl-airoha.c:2387:21: note: object 'status' of size 4 - 2387 | u32 status; - | ^~~~~~ - -Signed-off-by: Kees Cook -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/20241117114534.work.292-kees@kernel.org -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -2384,15 +2384,16 @@ static irqreturn_t airoha_irq_handler(in - - for (i = 0; i < ARRAY_SIZE(irq_status_regs); i++) { - struct gpio_irq_chip *girq = &pinctrl->gpiochip.chip.irq; -- u32 status; -+ u32 regmap; -+ unsigned long status; - int irq; - - if (regmap_read(pinctrl->regmap, pinctrl->gpiochip.status[i], -- &status)) -+ ®map)) - continue; - -- for_each_set_bit(irq, (unsigned long *)&status, -- AIROHA_PIN_BANK_SIZE) { -+ status = regmap; -+ for_each_set_bit(irq, &status, AIROHA_PIN_BANK_SIZE) { - u32 offset = irq + i * AIROHA_PIN_BANK_SIZE; - - generic_handle_irq(irq_find_mapping(girq->domain, diff --git a/target/linux/airoha/patches-6.12/036-v6.13-net-airoha-Fix-typo-in-REG_CDM2_FWD_CFG-configuratio.patch b/target/linux/airoha/patches-6.12/036-v6.13-net-airoha-Fix-typo-in-REG_CDM2_FWD_CFG-configuratio.patch deleted file mode 100644 index a71197150f4..00000000000 --- a/target/linux/airoha/patches-6.12/036-v6.13-net-airoha-Fix-typo-in-REG_CDM2_FWD_CFG-configuratio.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 30d9d8f6a2d7e44a9f91737dd409dbc87ac6f6b7 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 15 Oct 2024 09:58:09 +0200 -Subject: [PATCH] net: airoha: Fix typo in REG_CDM2_FWD_CFG configuration - -Fix typo in airoha_fe_init routine configuring CDM2_OAM_QSEL_MASK field -of REG_CDM2_FWD_CFG register. -This bug is not introducing any user visible problem since Frame Engine -CDM2 port is used just by the second QDMA block and we currently enable -just QDMA1 block connected to the MT7530 dsa switch via CDM1 port. - -Introduced by commit 23020f049327 ("net: airoha: Introduce ethernet -support for EN7581 SoC") - -Reported-by: ChihWei Cheng -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Message-ID: <20241015-airoha-eth-cdm2-fixes-v1-1-9dc6993286c3@kernel.org> -Signed-off-by: Andrew Lunn ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -1369,7 +1369,8 @@ static int airoha_fe_init(struct airoha_ - airoha_fe_set(eth, REG_GDM_MISC_CFG, - GDM2_RDM_ACK_WAIT_PREF_MASK | - GDM2_CHN_VLD_MODE_MASK); -- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, 15); -+ airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, -+ FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); - - /* init fragment and assemble Force Port */ - /* NPU Core-3, NPU Bridge Channel-3 */ diff --git a/target/linux/airoha/patches-6.12/038-01-v6.14-net-airoha-Enable-Tx-drop-capability-for-each-Tx-DMA.patch b/target/linux/airoha/patches-6.12/038-01-v6.14-net-airoha-Enable-Tx-drop-capability-for-each-Tx-DMA.patch deleted file mode 100644 index 27acb76b1e9..00000000000 --- a/target/linux/airoha/patches-6.12/038-01-v6.14-net-airoha-Enable-Tx-drop-capability-for-each-Tx-DMA.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 5f795590380476f1c9b7ed0ac945c9b0269dc23a Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 3 Jan 2025 13:17:02 +0100 -Subject: [PATCH 1/4] net: airoha: Enable Tx drop capability for each Tx DMA - ring - -This is a preliminary patch in order to enable hw Qdisc offloading. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -1810,6 +1810,10 @@ static int airoha_qdma_init_tx_queue(str - WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); - } - -+ /* xmit ring drop default setting */ -+ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), -+ TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK); -+ - airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); - airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, - FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); diff --git a/target/linux/airoha/patches-6.12/038-02-v6.14-net-airoha-Introduce-ndo_select_queue-callback.patch b/target/linux/airoha/patches-6.12/038-02-v6.14-net-airoha-Introduce-ndo_select_queue-callback.patch deleted file mode 100644 index 3110777ed94..00000000000 --- a/target/linux/airoha/patches-6.12/038-02-v6.14-net-airoha-Introduce-ndo_select_queue-callback.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 2b288b81560b94958cd68bbe54673e55a1730c95 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 3 Jan 2025 13:17:03 +0100 -Subject: [PATCH 2/4] net: airoha: Introduce ndo_select_queue callback - -Airoha EN7581 SoC supports 32 Tx DMA rings used to feed packets to QoS -channels. Each channels supports 8 QoS queues where the user can apply -QoS scheduling policies. In a similar way, the user can configure hw -rate shaping for each QoS channel. -Introduce ndo_select_queue callback in order to select the tx queue -based on QoS channel and QoS queue. In particular, for dsa device select -QoS channel according to the dsa user port index, rely on port id -otherwise. Select QoS queue based on the skb priority. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 30 ++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -23,6 +23,8 @@ - #define AIROHA_MAX_NUM_XSI_RSTS 5 - #define AIROHA_MAX_MTU 2000 - #define AIROHA_MAX_PACKET_SIZE 2048 -+#define AIROHA_NUM_QOS_CHANNELS 4 -+#define AIROHA_NUM_QOS_QUEUES 8 - #define AIROHA_NUM_TX_RING 32 - #define AIROHA_NUM_RX_RING 32 - #define AIROHA_FE_MC_MAX_VLAN_TABLE 64 -@@ -2442,21 +2444,44 @@ static void airoha_dev_get_stats64(struc - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } - -+static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ int queue, channel; -+ -+ /* For dsa device select QoS channel according to the dsa user port -+ * index, rely on port id otherwise. Select QoS queue based on the -+ * skb priority. -+ */ -+ channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; -+ channel = channel % AIROHA_NUM_QOS_CHANNELS; -+ queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ -+ queue = channel * AIROHA_NUM_QOS_QUEUES + queue; -+ -+ return queue < dev->num_tx_queues ? queue : 0; -+} -+ - static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, - struct net_device *dev) - { - struct skb_shared_info *sinfo = skb_shinfo(skb); - struct airoha_gdm_port *port = netdev_priv(dev); -- u32 msg0 = 0, msg1, len = skb_headlen(skb); -- int i, qid = skb_get_queue_mapping(skb); -+ u32 msg0, msg1, len = skb_headlen(skb); - struct airoha_qdma *qdma = port->qdma; - u32 nr_frags = 1 + sinfo->nr_frags; - struct netdev_queue *txq; - struct airoha_queue *q; - void *data = skb->data; -+ int i, qid; - u16 index; - u8 fport; - -+ qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); -+ msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, -+ qid / AIROHA_NUM_QOS_QUEUES) | -+ FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, -+ qid % AIROHA_NUM_QOS_QUEUES); - if (skb->ip_summed == CHECKSUM_PARTIAL) - msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | - FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | -@@ -2630,6 +2655,7 @@ static const struct net_device_ops airoh - .ndo_init = airoha_dev_init, - .ndo_open = airoha_dev_open, - .ndo_stop = airoha_dev_stop, -+ .ndo_select_queue = airoha_dev_select_queue, - .ndo_start_xmit = airoha_dev_xmit, - .ndo_get_stats64 = airoha_dev_get_stats64, - .ndo_set_mac_address = airoha_dev_set_macaddr, diff --git a/target/linux/airoha/patches-6.12/038-03-v6.14-net-airoha-Add-sched-ETS-offload-support.patch b/target/linux/airoha/patches-6.12/038-03-v6.14-net-airoha-Add-sched-ETS-offload-support.patch deleted file mode 100644 index aa4b0514659..00000000000 --- a/target/linux/airoha/patches-6.12/038-03-v6.14-net-airoha-Add-sched-ETS-offload-support.patch +++ /dev/null @@ -1,292 +0,0 @@ -From 20bf7d07c956e5c7a22d3076c599cbb7a6054917 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 3 Jan 2025 13:17:04 +0100 -Subject: [PATCH 3/4] net: airoha: Add sched ETS offload support - -Introduce support for ETS Qdisc offload available on the Airoha EN7581 -ethernet controller. In order to be effective, ETS Qdisc must configured -as leaf of a HTB Qdisc (HTB Qdisc offload will be added in the following -patch). ETS Qdisc available on EN7581 ethernet controller supports at -most 8 concurrent bands (QoS queues). We can enable an ETS Qdisc for -each available QoS channel. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 196 ++++++++++++++++++++- - 1 file changed, 195 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - - #define AIROHA_MAX_NUM_GDM_PORTS 1 -@@ -543,9 +544,24 @@ - #define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) - #define INGRESS_FAST_TICK_MASK GENMASK(15, 0) - -+#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) -+#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) -+ - #define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) - #define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) - -+#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) -+#define CNTR_EN_MASK BIT(31) -+#define CNTR_ALL_CHAN_EN_MASK BIT(30) -+#define CNTR_ALL_QUEUE_EN_MASK BIT(29) -+#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) -+#define CNTR_SRC_MASK GENMASK(27, 24) -+#define CNTR_DSCP_RING_MASK GENMASK(20, 16) -+#define CNTR_CHAN_MASK GENMASK(7, 3) -+#define CNTR_QUEUE_MASK GENMASK(2, 0) -+ -+#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) -+ - #define REG_LMGR_INIT_CFG 0x1000 - #define LMGR_INIT_START BIT(31) - #define LMGR_SRAM_MODE_MASK BIT(30) -@@ -571,9 +587,19 @@ - #define TWRR_WEIGHT_SCALE_MASK BIT(31) - #define TWRR_WEIGHT_BASE_MASK BIT(3) - -+#define REG_TXWRR_WEIGHT_CFG 0x1024 -+#define TWRR_RW_CMD_MASK BIT(31) -+#define TWRR_RW_CMD_DONE BIT(30) -+#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) -+#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) -+#define TWRR_VALUE_MASK GENMASK(15, 0) -+ - #define REG_PSE_BUF_USAGE_CFG 0x1028 - #define PSE_BUF_ESTIMATE_EN_MASK BIT(29) - -+#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) -+#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) -+ - #define REG_GLB_TRTCM_CFG 0x1080 - #define GLB_TRTCM_EN_MASK BIT(31) - #define GLB_TRTCM_MODE_MASK BIT(30) -@@ -722,6 +748,17 @@ enum { - FE_PSE_PORT_DROP = 0xf, - }; - -+enum tx_sched_mode { -+ TC_SCH_WRR8, -+ TC_SCH_SP, -+ TC_SCH_WRR7, -+ TC_SCH_WRR6, -+ TC_SCH_WRR5, -+ TC_SCH_WRR4, -+ TC_SCH_WRR3, -+ TC_SCH_WRR2, -+}; -+ - struct airoha_queue_entry { - union { - void *buf; -@@ -812,6 +849,10 @@ struct airoha_gdm_port { - int id; - - struct airoha_hw_stats stats; -+ -+ /* qos stats counters */ -+ u64 cpu_tx_packets; -+ u64 fwd_tx_packets; - }; - - struct airoha_eth { -@@ -1982,6 +2023,27 @@ static void airoha_qdma_init_qos(struct - FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40)); - } - -+static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ for (i = 0; i < AIROHA_NUM_QOS_CHANNELS; i++) { -+ /* Tx-cpu transferred count */ -+ airoha_qdma_wr(qdma, REG_CNTR_VAL(i << 1), 0); -+ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), -+ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | -+ CNTR_ALL_DSCP_RING_EN_MASK | -+ FIELD_PREP(CNTR_CHAN_MASK, i)); -+ /* Tx-fwd transferred count */ -+ airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0); -+ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), -+ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | -+ CNTR_ALL_DSCP_RING_EN_MASK | -+ FIELD_PREP(CNTR_SRC_MASK, 1) | -+ FIELD_PREP(CNTR_CHAN_MASK, i)); -+ } -+} -+ - static int airoha_qdma_hw_init(struct airoha_qdma *qdma) - { - int i; -@@ -2032,6 +2094,7 @@ static int airoha_qdma_hw_init(struct ai - - airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG, - TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN); -+ airoha_qdma_init_qos_stats(qdma); - - return 0; - } -@@ -2651,6 +2714,135 @@ airoha_ethtool_get_rmon_stats(struct net - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } - -+static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port, -+ int channel, enum tx_sched_mode mode, -+ const u16 *weights, u8 n_weights) -+{ -+ int i; -+ -+ for (i = 0; i < AIROHA_NUM_TX_RING; i++) -+ airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), -+ TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)); -+ -+ for (i = 0; i < n_weights; i++) { -+ u32 status; -+ int err; -+ -+ airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, -+ TWRR_RW_CMD_MASK | -+ FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) | -+ FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) | -+ FIELD_PREP(TWRR_VALUE_MASK, weights[i])); -+ err = read_poll_timeout(airoha_qdma_rr, status, -+ status & TWRR_RW_CMD_DONE, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, -+ true, port->qdma, -+ REG_TXWRR_WEIGHT_CFG); -+ if (err) -+ return err; -+ } -+ -+ airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), -+ CHAN_QOS_MODE_MASK(channel), -+ mode << __ffs(CHAN_QOS_MODE_MASK(channel))); -+ -+ return 0; -+} -+ -+static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port, -+ int channel) -+{ -+ static const u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -+ -+ return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w, -+ ARRAY_SIZE(w)); -+} -+ -+static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port, -+ int channel, -+ struct tc_ets_qopt_offload *opt) -+{ -+ struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; -+ enum tx_sched_mode mode = TC_SCH_SP; -+ u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -+ int i, nstrict = 0; -+ -+ if (p->bands > AIROHA_NUM_QOS_QUEUES) -+ return -EINVAL; -+ -+ for (i = 0; i < p->bands; i++) { -+ if (!p->quanta[i]) -+ nstrict++; -+ } -+ -+ /* this configuration is not supported by the hw */ -+ if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) -+ return -EINVAL; -+ -+ for (i = 0; i < p->bands - nstrict; i++) -+ w[i] = p->weights[nstrict + i]; -+ -+ if (!nstrict) -+ mode = TC_SCH_WRR8; -+ else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) -+ mode = nstrict + 1; -+ -+ return airoha_qdma_set_chan_tx_sched(port, channel, mode, w, -+ ARRAY_SIZE(w)); -+} -+ -+static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port, -+ int channel, -+ struct tc_ets_qopt_offload *opt) -+{ -+ u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, -+ REG_CNTR_VAL(channel << 1)); -+ u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, -+ REG_CNTR_VAL((channel << 1) + 1)); -+ u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + -+ (fwd_tx_packets - port->fwd_tx_packets); -+ _bstats_update(opt->stats.bstats, 0, tx_packets); -+ -+ port->cpu_tx_packets = cpu_tx_packets; -+ port->fwd_tx_packets = fwd_tx_packets; -+ -+ return 0; -+} -+ -+static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, -+ struct tc_ets_qopt_offload *opt) -+{ -+ int channel = TC_H_MAJ(opt->handle) >> 16; -+ -+ if (opt->parent == TC_H_ROOT) -+ return -EINVAL; -+ -+ switch (opt->command) { -+ case TC_ETS_REPLACE: -+ return airoha_qdma_set_tx_ets_sched(port, channel, opt); -+ case TC_ETS_DESTROY: -+ /* PRIO is default qdisc scheduler */ -+ return airoha_qdma_set_tx_prio_sched(port, channel); -+ case TC_ETS_STATS: -+ return airoha_qdma_get_tx_ets_stats(port, channel, opt); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, -+ void *type_data) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ -+ switch (type) { -+ case TC_SETUP_QDISC_ETS: -+ return airoha_tc_setup_qdisc_ets(port, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - static const struct net_device_ops airoha_netdev_ops = { - .ndo_init = airoha_dev_init, - .ndo_open = airoha_dev_open, -@@ -2659,6 +2851,7 @@ static const struct net_device_ops airoh - .ndo_start_xmit = airoha_dev_xmit, - .ndo_get_stats64 = airoha_dev_get_stats64, - .ndo_set_mac_address = airoha_dev_set_macaddr, -+ .ndo_setup_tc = airoha_dev_tc_setup, - }; - - static const struct ethtool_ops airoha_ethtool_ops = { -@@ -2708,7 +2901,8 @@ static int airoha_alloc_gdm_port(struct - dev->watchdog_timeo = 5 * HZ; - dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | - NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | -- NETIF_F_SG | NETIF_F_TSO; -+ NETIF_F_SG | NETIF_F_TSO | -+ NETIF_F_HW_TC; - dev->features |= dev->hw_features; - dev->dev.of_node = np; - dev->irq = qdma->irq; diff --git a/target/linux/airoha/patches-6.12/038-04-v6.14-net-airoha-Add-sched-HTB-offload-support.patch b/target/linux/airoha/patches-6.12/038-04-v6.14-net-airoha-Add-sched-HTB-offload-support.patch deleted file mode 100644 index 405f095d590..00000000000 --- a/target/linux/airoha/patches-6.12/038-04-v6.14-net-airoha-Add-sched-HTB-offload-support.patch +++ /dev/null @@ -1,371 +0,0 @@ -From ef1ca9271313b4ea7b03de69576aacef1e78f381 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 3 Jan 2025 13:17:05 +0100 -Subject: [PATCH 4/4] net: airoha: Add sched HTB offload support - -Introduce support for HTB Qdisc offload available in the Airoha EN7581 -ethernet controller. EN7581 can offload only one level of HTB leafs. -Each HTB leaf represents a QoS channel supported by EN7581 SoC. -The typical use-case is creating a HTB leaf for QoS channel to rate -limit the egress traffic and attach an ETS Qdisc to each HTB leaf in -order to enforce traffic prioritization. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 288 ++++++++++++++++++++- - 1 file changed, 287 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -28,6 +28,8 @@ - #define AIROHA_NUM_QOS_QUEUES 8 - #define AIROHA_NUM_TX_RING 32 - #define AIROHA_NUM_RX_RING 32 -+#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ -+ AIROHA_NUM_QOS_CHANNELS) - #define AIROHA_FE_MC_MAX_VLAN_TABLE 64 - #define AIROHA_FE_MC_MAX_VLAN_PORT 16 - #define AIROHA_NUM_TX_IRQ 2 -@@ -43,6 +45,9 @@ - #define PSE_RSV_PAGES 128 - #define PSE_QUEUE_RSV_PAGES 64 - -+#define QDMA_METER_IDX(_n) ((_n) & 0xff) -+#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) -+ - /* FE */ - #define PSE_BASE 0x0100 - #define CSR_IFC_BASE 0x0200 -@@ -583,6 +588,17 @@ - #define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) - #define EGRESS_FAST_TICK_MASK GENMASK(15, 0) - -+#define TRTCM_PARAM_RW_MASK BIT(31) -+#define TRTCM_PARAM_RW_DONE_MASK BIT(30) -+#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) -+#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) -+#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) -+#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) -+ -+#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) -+#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) -+#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) -+ - #define REG_TXWRR_MODE_CFG 0x1020 - #define TWRR_WEIGHT_SCALE_MASK BIT(31) - #define TWRR_WEIGHT_BASE_MASK BIT(3) -@@ -759,6 +775,29 @@ enum tx_sched_mode { - TC_SCH_WRR2, - }; - -+enum trtcm_param_type { -+ TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ -+ TRTCM_TOKEN_RATE_MODE, -+ TRTCM_BUCKETSIZE_SHIFT_MODE, -+ TRTCM_BUCKET_COUNTER_MODE, -+}; -+ -+enum trtcm_mode_type { -+ TRTCM_COMMIT_MODE, -+ TRTCM_PEAK_MODE, -+}; -+ -+enum trtcm_param { -+ TRTCM_TICK_SEL = BIT(0), -+ TRTCM_PKT_MODE = BIT(1), -+ TRTCM_METER_MODE = BIT(2), -+}; -+ -+#define MIN_TOKEN_SIZE 4096 -+#define MAX_TOKEN_SIZE_OFFSET 17 -+#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) -+#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) -+ - struct airoha_queue_entry { - union { - void *buf; -@@ -850,6 +889,8 @@ struct airoha_gdm_port { - - struct airoha_hw_stats stats; - -+ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); -+ - /* qos stats counters */ - u64 cpu_tx_packets; - u64 fwd_tx_packets; -@@ -2830,6 +2871,243 @@ static int airoha_tc_setup_qdisc_ets(str - } - } - -+static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, -+ u32 addr, enum trtcm_param_type param, -+ enum trtcm_mode_type mode, -+ u32 *val_low, u32 *val_high) -+{ -+ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); -+ u32 val, config = FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | -+ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | -+ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | -+ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); -+ -+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -+ if (read_poll_timeout(airoha_qdma_rr, val, -+ val & TRTCM_PARAM_RW_DONE_MASK, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, -+ qdma, REG_TRTCM_CFG_PARAM(addr))) -+ return -ETIMEDOUT; -+ -+ *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); -+ if (val_high) -+ *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); -+ -+ return 0; -+} -+ -+static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel, -+ u32 addr, enum trtcm_param_type param, -+ enum trtcm_mode_type mode, u32 val) -+{ -+ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); -+ u32 config = TRTCM_PARAM_RW_MASK | -+ FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | -+ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | -+ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | -+ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); -+ -+ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); -+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -+ -+ return read_poll_timeout(airoha_qdma_rr, val, -+ val & TRTCM_PARAM_RW_DONE_MASK, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, -+ qdma, REG_TRTCM_CFG_PARAM(addr)); -+} -+ -+static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel, -+ u32 addr, enum trtcm_mode_type mode, -+ bool enable, u32 enable_mask) -+{ -+ u32 val; -+ -+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -+ mode, &val, NULL)) -+ return -EINVAL; -+ -+ val = enable ? val | enable_mask : val & ~enable_mask; -+ -+ return airoha_qdma_set_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -+ mode, val); -+} -+ -+static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma, -+ int channel, u32 addr, -+ enum trtcm_mode_type mode, -+ u32 rate_val, u32 bucket_size) -+{ -+ u32 val, config, tick, unit, rate, rate_frac; -+ int err; -+ -+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -+ mode, &config, NULL)) -+ return -EINVAL; -+ -+ val = airoha_qdma_rr(qdma, addr); -+ tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); -+ if (config & TRTCM_TICK_SEL) -+ tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); -+ if (!tick) -+ return -EINVAL; -+ -+ unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; -+ if (!unit) -+ return -EINVAL; -+ -+ rate = rate_val / unit; -+ rate_frac = rate_val % unit; -+ rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; -+ rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | -+ FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); -+ -+ err = airoha_qdma_set_trtcm_param(qdma, channel, addr, -+ TRTCM_TOKEN_RATE_MODE, mode, rate); -+ if (err) -+ return err; -+ -+ val = max_t(u32, bucket_size, MIN_TOKEN_SIZE); -+ val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); -+ -+ return airoha_qdma_set_trtcm_param(qdma, channel, addr, -+ TRTCM_BUCKETSIZE_SHIFT_MODE, -+ mode, val); -+} -+ -+static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port, -+ int channel, u32 rate, -+ u32 bucket_size) -+{ -+ int i, err; -+ -+ for (i = 0; i <= TRTCM_PEAK_MODE; i++) { -+ err = airoha_qdma_set_trtcm_config(port->qdma, channel, -+ REG_EGRESS_TRTCM_CFG, i, -+ !!rate, TRTCM_METER_MODE); -+ if (err) -+ return err; -+ -+ err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, -+ REG_EGRESS_TRTCM_CFG, -+ i, rate, bucket_size); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ -+ struct net_device *dev = port->dev; -+ int num_tx_queues = dev->real_num_tx_queues; -+ int err; -+ -+ if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { -+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); -+ return -EINVAL; -+ } -+ -+ err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); -+ if (err) { -+ NL_SET_ERR_MSG_MOD(opt->extack, -+ "failed configuring htb offload"); -+ return err; -+ } -+ -+ if (opt->command == TC_HTB_NODE_MODIFY) -+ return 0; -+ -+ err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); -+ if (err) { -+ airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); -+ NL_SET_ERR_MSG_MOD(opt->extack, -+ "failed setting real_num_tx_queues"); -+ return err; -+ } -+ -+ set_bit(channel, port->qos_sq_bmap); -+ opt->qid = AIROHA_NUM_TX_RING + channel; -+ -+ return 0; -+} -+ -+static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) -+{ -+ struct net_device *dev = port->dev; -+ -+ netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); -+ airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0); -+ clear_bit(queue, port->qos_sq_bmap); -+} -+ -+static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ -+ if (!test_bit(channel, port->qos_sq_bmap)) { -+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -+ return -EINVAL; -+ } -+ -+ airoha_tc_remove_htb_queue(port, channel); -+ -+ return 0; -+} -+ -+static int airoha_tc_htb_destroy(struct airoha_gdm_port *port) -+{ -+ int q; -+ -+ for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) -+ airoha_tc_remove_htb_queue(port, q); -+ -+ return 0; -+} -+ -+static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ -+ if (!test_bit(channel, port->qos_sq_bmap)) { -+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -+ return -EINVAL; -+ } -+ -+ opt->qid = channel; -+ -+ return 0; -+} -+ -+static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ switch (opt->command) { -+ case TC_HTB_CREATE: -+ break; -+ case TC_HTB_DESTROY: -+ return airoha_tc_htb_destroy(port); -+ case TC_HTB_NODE_MODIFY: -+ case TC_HTB_LEAF_ALLOC_QUEUE: -+ return airoha_tc_htb_alloc_leaf_queue(port, opt); -+ case TC_HTB_LEAF_DEL: -+ case TC_HTB_LEAF_DEL_LAST: -+ case TC_HTB_LEAF_DEL_LAST_FORCE: -+ return airoha_tc_htb_delete_leaf_queue(port, opt); -+ case TC_HTB_LEAF_QUERY_QUEUE: -+ return airoha_tc_get_htb_get_leaf_queue(port, opt); -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ - static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, - void *type_data) - { -@@ -2838,6 +3116,8 @@ static int airoha_dev_tc_setup(struct ne - switch (type) { - case TC_SETUP_QDISC_ETS: - return airoha_tc_setup_qdisc_ets(port, type_data); -+ case TC_SETUP_QDISC_HTB: -+ return airoha_tc_setup_qdisc_htb(port, type_data); - default: - return -EOPNOTSUPP; - } -@@ -2888,7 +3168,8 @@ static int airoha_alloc_gdm_port(struct - } - - dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), -- AIROHA_NUM_TX_RING, AIROHA_NUM_RX_RING); -+ AIROHA_NUM_NETDEV_TX_RINGS, -+ AIROHA_NUM_RX_RING); - if (!dev) { - dev_err(eth->dev, "alloc_etherdev failed\n"); - return -ENOMEM; -@@ -2908,6 +3189,11 @@ static int airoha_alloc_gdm_port(struct - dev->irq = qdma->irq; - SET_NETDEV_DEV(dev, eth->dev); - -+ /* reserve hw queues for HTB offloading */ -+ err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING); -+ if (err) -+ return err; -+ - err = of_get_ethdev_address(np, dev); - if (err) { - if (err == -EPROBE_DEFER) diff --git a/target/linux/airoha/patches-6.12/039-v6.14-cpufreq-airoha-Add-EN7581-CPUFreq-SMCCC-driver.patch b/target/linux/airoha/patches-6.12/039-v6.14-cpufreq-airoha-Add-EN7581-CPUFreq-SMCCC-driver.patch deleted file mode 100644 index 96d7f66da9e..00000000000 --- a/target/linux/airoha/patches-6.12/039-v6.14-cpufreq-airoha-Add-EN7581-CPUFreq-SMCCC-driver.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 84cf9e541cccb8cb698518a9897942e8c78f1d83 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 9 Jan 2025 14:12:58 +0100 -Subject: [PATCH] cpufreq: airoha: Add EN7581 CPUFreq SMCCC driver - -Add simple CPU Freq driver for Airoha EN7581 SoC that control CPU -frequency scaling with SMC APIs and register a generic "cpufreq-dt" -device. - -All CPU share the same frequency and can't be controlled independently. -CPU frequency is controlled by the attached PM domain. - -Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq -driver is needed with OPP v2 nodes declared in DTS. - -Signed-off-by: Christian Marangi -Signed-off-by: Viresh Kumar ---- - drivers/cpufreq/Kconfig.arm | 8 ++ - drivers/cpufreq/Makefile | 1 + - drivers/cpufreq/airoha-cpufreq.c | 152 +++++++++++++++++++++++++++ - drivers/cpufreq/cpufreq-dt-platdev.c | 2 + - 4 files changed, 163 insertions(+) - create mode 100644 drivers/cpufreq/airoha-cpufreq.c - ---- a/drivers/cpufreq/Kconfig.arm -+++ b/drivers/cpufreq/Kconfig.arm -@@ -15,6 +15,14 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVME - To compile this driver as a module, choose M here: the - module will be called sun50i-cpufreq-nvmem. - -+config ARM_AIROHA_SOC_CPUFREQ -+ tristate "Airoha EN7581 SoC CPUFreq support" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ select PM_OPP -+ default ARCH_AIROHA -+ help -+ This adds the CPUFreq driver for Airoha EN7581 SoCs. -+ - config ARM_APPLE_SOC_CPUFREQ - tristate "Apple Silicon SoC CPUFreq support" - depends on ARCH_APPLE || (COMPILE_TEST && 64BIT) ---- a/drivers/cpufreq/Makefile -+++ b/drivers/cpufreq/Makefile -@@ -52,6 +52,7 @@ obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) + - - ################################################################################## - # ARM SoC drivers -+obj-$(CONFIG_ARM_AIROHA_SOC_CPUFREQ) += airoha-cpufreq.o - obj-$(CONFIG_ARM_APPLE_SOC_CPUFREQ) += apple-soc-cpufreq.o - obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o - obj-$(CONFIG_ARM_ARMADA_8K_CPUFREQ) += armada-8k-cpufreq.o ---- /dev/null -+++ b/drivers/cpufreq/airoha-cpufreq.c -@@ -0,0 +1,166 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "cpufreq-dt.h" -+ -+struct airoha_cpufreq_priv { -+ int opp_token; -+ struct device **virt_devs; -+ struct platform_device *cpufreq_dt; -+}; -+ -+static struct platform_device *cpufreq_pdev; -+ -+/* NOP function to disable OPP from setting clock */ -+static int airoha_cpufreq_config_clks_nop(struct device *dev, -+ struct opp_table *opp_table, -+ struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, -+ void *data, bool scaling_down) -+{ -+ return 0; -+} -+ -+static const char * const airoha_cpufreq_clk_names[] = { "cpu", NULL }; -+static const char * const airoha_cpufreq_pd_names[] = { "perf", NULL }; -+ -+static int airoha_cpufreq_probe(struct platform_device *pdev) -+{ -+ struct dev_pm_opp_config config = { -+ .clk_names = airoha_cpufreq_clk_names, -+ .config_clks = airoha_cpufreq_config_clks_nop, -+ .genpd_names = airoha_cpufreq_pd_names, -+ }; -+ struct platform_device *cpufreq_dt; -+ struct airoha_cpufreq_priv *priv; -+ struct device *dev = &pdev->dev; -+ struct device **virt_devs = NULL; -+ struct device *cpu_dev; -+ int ret; -+ -+ /* CPUs refer to the same OPP table */ -+ cpu_dev = get_cpu_device(0); -+ if (!cpu_dev) -+ return -ENODEV; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ /* Set OPP table conf with NOP config_clks */ -+ priv->opp_token = dev_pm_opp_set_config(cpu_dev, &config); -+ if (priv->opp_token < 0) -+ return dev_err_probe(dev, priv->opp_token, "Failed to set OPP config\n"); -+ -+ /* Set Attached PM for OPP ACTIVE */ -+ if (virt_devs) { -+ const char * const *name = airoha_cpufreq_pd_names; -+ int i, j; -+ -+ for (i = 0; *name; i++, name++) { -+ ret = pm_runtime_resume_and_get(virt_devs[i]); -+ if (ret) { -+ dev_err(cpu_dev, "failed to resume %s: %d\n", -+ *name, ret); -+ -+ /* Rollback previous PM runtime calls */ -+ name = config.genpd_names; -+ for (j = 0; *name && j < i; j++, name++) -+ pm_runtime_put(virt_devs[j]); -+ -+ goto err_register_cpufreq; -+ } -+ } -+ priv->virt_devs = virt_devs; -+ } -+ -+ cpufreq_dt = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); -+ ret = PTR_ERR_OR_ZERO(cpufreq_dt); -+ if (ret) { -+ dev_err(dev, "failed to create cpufreq-dt device: %d\n", ret); -+ goto err_register_cpufreq; -+ } -+ -+ priv->cpufreq_dt = cpufreq_dt; -+ platform_set_drvdata(pdev, priv); -+ -+ return 0; -+ -+err_register_cpufreq: -+ dev_pm_opp_clear_config(priv->opp_token); -+ -+ return ret; -+} -+ -+static void airoha_cpufreq_remove(struct platform_device *pdev) -+{ -+ struct airoha_cpufreq_priv *priv = platform_get_drvdata(pdev); -+ const char * const *name = airoha_cpufreq_pd_names; -+ int i; -+ -+ platform_device_unregister(priv->cpufreq_dt); -+ -+ dev_pm_opp_clear_config(priv->opp_token); -+ -+ for (i = 0; *name; i++, name++) -+ pm_runtime_put(priv->virt_devs[i]); -+} -+ -+static struct platform_driver airoha_cpufreq_driver = { -+ .probe = airoha_cpufreq_probe, -+ .remove_new = airoha_cpufreq_remove, -+ .driver = { -+ .name = "airoha-cpufreq", -+ }, -+}; -+ -+static const struct of_device_id airoha_cpufreq_match_list[] __initconst = { -+ { .compatible = "airoha,en7581" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, airoha_cpufreq_match_list); -+ -+static int __init airoha_cpufreq_init(void) -+{ -+ struct device_node *np = of_find_node_by_path("/"); -+ const struct of_device_id *match; -+ int ret; -+ -+ if (!np) -+ return -ENODEV; -+ -+ match = of_match_node(airoha_cpufreq_match_list, np); -+ of_node_put(np); -+ if (!match) -+ return -ENODEV; -+ -+ ret = platform_driver_register(&airoha_cpufreq_driver); -+ if (unlikely(ret < 0)) -+ return ret; -+ -+ cpufreq_pdev = platform_device_register_data(NULL, "airoha-cpufreq", -+ -1, match, sizeof(*match)); -+ ret = PTR_ERR_OR_ZERO(cpufreq_pdev); -+ if (ret) -+ platform_driver_unregister(&airoha_cpufreq_driver); -+ -+ return ret; -+} -+module_init(airoha_cpufreq_init); -+ -+static void __exit airoha_cpufreq_exit(void) -+{ -+ platform_device_unregister(cpufreq_pdev); -+ platform_driver_unregister(&airoha_cpufreq_driver); -+} -+module_exit(airoha_cpufreq_exit); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("CPUfreq driver for Airoha SoCs"); -+MODULE_LICENSE("GPL"); ---- a/drivers/cpufreq/cpufreq-dt-platdev.c -+++ b/drivers/cpufreq/cpufreq-dt-platdev.c -@@ -104,6 +104,8 @@ static const struct of_device_id allowli - * platforms using "operating-points-v2" property. - */ - static const struct of_device_id blocklist[] __initconst = { -+ { .compatible = "airoha,en7581", }, -+ - { .compatible = "allwinner,sun50i-h6", }, - { .compatible = "allwinner,sun50i-h616", }, - { .compatible = "allwinner,sun50i-h618", }, diff --git a/target/linux/airoha/patches-6.12/039-v6.14-net-airoha-Enforce-ETS-Qdisc-priomap.patch b/target/linux/airoha/patches-6.12/039-v6.14-net-airoha-Enforce-ETS-Qdisc-priomap.patch deleted file mode 100644 index daa7c2264bb..00000000000 --- a/target/linux/airoha/patches-6.12/039-v6.14-net-airoha-Enforce-ETS-Qdisc-priomap.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b56e4d660a9688ff83f5cbdc6e3ea063352d0d79 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Jan 2025 19:32:45 +0100 -Subject: [PATCH] net: airoha: Enforce ETS Qdisc priomap - -EN7581 SoC supports fixed QoS band priority where WRR queues have lowest -priorities with respect to SP ones. -E.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn - -Enforce ETS Qdisc priomap according to the hw capabilities. - -Suggested-by: Davide Caratti -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Davide Caratti -Link: https://patch.msgid.link/20250112-airoha_ets_priomap-v1-1-fb616de159ba@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -2806,7 +2806,7 @@ static int airoha_qdma_set_tx_ets_sched( - struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; - enum tx_sched_mode mode = TC_SCH_SP; - u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -- int i, nstrict = 0; -+ int i, nstrict = 0, nwrr, qidx; - - if (p->bands > AIROHA_NUM_QOS_QUEUES) - return -EINVAL; -@@ -2820,7 +2820,20 @@ static int airoha_qdma_set_tx_ets_sched( - if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) - return -EINVAL; - -- for (i = 0; i < p->bands - nstrict; i++) -+ /* EN7581 SoC supports fixed QoS band priority where WRR queues have -+ * lowest priorities with respect to SP ones. -+ * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn -+ */ -+ nwrr = p->bands - nstrict; -+ qidx = nstrict && nwrr ? nstrict : 0; -+ for (i = 1; i <= p->bands; i++) { -+ if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) -+ return -EINVAL; -+ -+ qidx = i == nwrr ? 0 : qidx + 1; -+ } -+ -+ for (i = 0; i < nwrr; i++) - w[i] = p->weights[nstrict + i]; - - if (!nstrict) diff --git a/target/linux/airoha/patches-6.12/040-v6.14-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch b/target/linux/airoha/patches-6.12/040-v6.14-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch deleted file mode 100644 index 8dc8a3d304a..00000000000 --- a/target/linux/airoha/patches-6.12/040-v6.14-pmdomain-airoha-Add-Airoha-CPU-PM-Domain-support.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 82e703dd438b71432cc0ccbb90925d1e32dd014a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 9 Jan 2025 14:12:57 +0100 -Subject: [PATCH] pmdomain: airoha: Add Airoha CPU PM Domain support - -Add Airoha CPU PM Domain support to control frequency and power of CPU -present on Airoha EN7581 SoC. - -Frequency and power can be controlled with the use of the SMC command by -passing the performance state. The driver also expose a read-only clock -that expose the current CPU frequency with SMC command. - -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20250109131313.32317-1-ansuelsmth@gmail.com -Signed-off-by: Ulf Hansson ---- - drivers/pmdomain/mediatek/Kconfig | 12 ++ - drivers/pmdomain/mediatek/Makefile | 1 + - .../pmdomain/mediatek/airoha-cpu-pmdomain.c | 144 ++++++++++++++++++ - 3 files changed, 157 insertions(+) - create mode 100644 drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c - ---- a/drivers/soc/mediatek/Kconfig -+++ b/drivers/soc/mediatek/Kconfig -@@ -2,6 +2,17 @@ - # - # MediaTek SoC drivers - # -+config AIROHA_CPU_PM_DOMAIN -+ tristate "Airoha CPU power domain" -+ default ARCH_AIROHA -+ depends on PM -+ select PM_GENERIC_DOMAINS -+ help -+ Say y here to enable CPU power domain support for Airoha SoC. -+ -+ CPU frequency and power is controlled by ATF with SMC command to -+ set performance states. -+ - menu "MediaTek SoC drivers" - depends on ARCH_MEDIATEK || COMPILE_TEST - ---- a/drivers/pmdomain/mediatek/Makefile -+++ b/drivers/pmdomain/mediatek/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0-only - obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o - obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o -+obj-$(CONFIG_AIROHA_CPU_PM_DOMAIN) += airoha-cpu-pmdomain.o ---- /dev/null -+++ b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c -@@ -0,0 +1,144 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define AIROHA_SIP_AVS_HANDLE 0x82000301 -+#define AIROHA_AVS_OP_BASE 0xddddddd0 -+#define AIROHA_AVS_OP_MASK GENMASK(1, 0) -+#define AIROHA_AVS_OP_FREQ_DYN_ADJ (AIROHA_AVS_OP_BASE | \ -+ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x1)) -+#define AIROHA_AVS_OP_GET_FREQ (AIROHA_AVS_OP_BASE | \ -+ FIELD_PREP(AIROHA_AVS_OP_MASK, 0x2)) -+ -+struct airoha_cpu_pmdomain_priv { -+ struct clk_hw hw; -+ struct generic_pm_domain pd; -+}; -+ -+static long airoha_cpu_pmdomain_clk_round(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ return rate; -+} -+ -+static unsigned long airoha_cpu_pmdomain_clk_get(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct arm_smccc_res res; -+ -+ arm_smccc_1_1_invoke(AIROHA_SIP_AVS_HANDLE, AIROHA_AVS_OP_GET_FREQ, -+ 0, 0, 0, 0, 0, 0, &res); -+ -+ /* SMCCC returns freq in MHz */ -+ return (int)(res.a0 * 1000 * 1000); -+} -+ -+/* Airoha CPU clk SMCC is always enabled */ -+static int airoha_cpu_pmdomain_clk_is_enabled(struct clk_hw *hw) -+{ -+ return true; -+} -+ -+static const struct clk_ops airoha_cpu_pmdomain_clk_ops = { -+ .recalc_rate = airoha_cpu_pmdomain_clk_get, -+ .is_enabled = airoha_cpu_pmdomain_clk_is_enabled, -+ .round_rate = airoha_cpu_pmdomain_clk_round, -+}; -+ -+static int airoha_cpu_pmdomain_set_performance_state(struct generic_pm_domain *domain, -+ unsigned int state) -+{ -+ struct arm_smccc_res res; -+ -+ arm_smccc_1_1_invoke(AIROHA_SIP_AVS_HANDLE, AIROHA_AVS_OP_FREQ_DYN_ADJ, -+ 0, state, 0, 0, 0, 0, &res); -+ -+ /* SMC signal correct apply by unsetting BIT 0 */ -+ return res.a0 & BIT(0) ? -EINVAL : 0; -+} -+ -+static int airoha_cpu_pmdomain_probe(struct platform_device *pdev) -+{ -+ struct airoha_cpu_pmdomain_priv *priv; -+ struct device *dev = &pdev->dev; -+ const struct clk_init_data init = { -+ .name = "cpu", -+ .ops = &airoha_cpu_pmdomain_clk_ops, -+ /* Clock with no set_rate, can't cache */ -+ .flags = CLK_GET_RATE_NOCACHE, -+ }; -+ struct generic_pm_domain *pd; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ /* Init and register a get-only clk for Cpufreq */ -+ priv->hw.init = &init; -+ ret = devm_clk_hw_register(dev, &priv->hw); -+ if (ret) -+ return ret; -+ -+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, -+ &priv->hw); -+ if (ret) -+ return ret; -+ -+ /* Init and register a PD for CPU */ -+ pd = &priv->pd; -+ pd->name = "cpu_pd"; -+ pd->flags = GENPD_FLAG_ALWAYS_ON; -+ pd->set_performance_state = airoha_cpu_pmdomain_set_performance_state; -+ -+ ret = pm_genpd_init(pd, NULL, false); -+ if (ret) -+ return ret; -+ -+ ret = of_genpd_add_provider_simple(dev->of_node, pd); -+ if (ret) -+ goto err_add_provider; -+ -+ platform_set_drvdata(pdev, priv); -+ -+ return 0; -+ -+err_add_provider: -+ pm_genpd_remove(pd); -+ -+ return ret; -+} -+ -+static void airoha_cpu_pmdomain_remove(struct platform_device *pdev) -+{ -+ struct airoha_cpu_pmdomain_priv *priv = platform_get_drvdata(pdev); -+ -+ of_genpd_del_provider(pdev->dev.of_node); -+ pm_genpd_remove(&priv->pd); -+} -+ -+static const struct of_device_id airoha_cpu_pmdomain_of_match[] = { -+ { .compatible = "airoha,en7581-cpufreq" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, airoha_cpu_pmdomain_of_match); -+ -+static struct platform_driver airoha_cpu_pmdomain_driver = { -+ .probe = airoha_cpu_pmdomain_probe, -+ .remove_new = airoha_cpu_pmdomain_remove, -+ .driver = { -+ .name = "airoha-cpu-pmdomain", -+ .of_match_table = airoha_cpu_pmdomain_of_match, -+ }, -+}; -+module_platform_driver(airoha_cpu_pmdomain_driver); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("CPU PM domain driver for Airoha SoCs"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/041-01-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch b/target/linux/airoha/patches-6.12/041-01-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch deleted file mode 100644 index 96d2bbf28ef..00000000000 --- a/target/linux/airoha/patches-6.12/041-01-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch +++ /dev/null @@ -1,83 +0,0 @@ -From e4a9748e7103c47e575459db2b6a77d14f34da2b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Jan 2025 00:10:02 +0100 -Subject: [PATCH 1/4] clk: en7523: Rework clock handling for different clock - numbers - -Airoha EN7581 SoC have additional clock compared to EN7523 but current -driver permits to only support up to EN7523 clock numbers. - -To handle this, rework the clock handling and permit to declare the -clocks number in match_data and alloca clk_data based on the compatible -match_data. - -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20250113231030.6735-2-ansuelsmth@gmail.com -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-en7523.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -75,6 +75,7 @@ struct en_rst_data { - }; - - struct en_clk_soc_data { -+ u32 num_clocks; - const struct clk_ops pcie_ops; - int (*hw_init)(struct platform_device *pdev, - struct clk_hw_onecell_data *clk_data); -@@ -504,8 +505,6 @@ static void en7523_register_clocks(struc - u32 rate; - int i; - -- clk_data->num = EN7523_NUM_CLOCKS; -- - for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { - const struct en_clk_desc *desc = &en7523_base_clks[i]; - u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; -@@ -587,8 +586,6 @@ static void en7581_register_clocks(struc - - hw = en7523_register_pcie_clk(dev, base); - clk_data->hws[EN7523_CLK_PCIE] = hw; -- -- clk_data->num = EN7523_NUM_CLOCKS; - } - - static int en7523_reset_update(struct reset_controller_dev *rcdev, -@@ -702,13 +699,15 @@ static int en7523_clk_probe(struct platf - struct clk_hw_onecell_data *clk_data; - int r; - -+ soc_data = device_get_match_data(&pdev->dev); -+ - clk_data = devm_kzalloc(&pdev->dev, -- struct_size(clk_data, hws, EN7523_NUM_CLOCKS), -+ struct_size(clk_data, hws, soc_data->num_clocks), - GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - -- soc_data = device_get_match_data(&pdev->dev); -+ clk_data->num = soc_data->num_clocks; - r = soc_data->hw_init(pdev, clk_data); - if (r) - return r; -@@ -717,6 +716,7 @@ static int en7523_clk_probe(struct platf - } - - static const struct en_clk_soc_data en7523_data = { -+ .num_clocks = ARRAY_SIZE(en7523_base_clks) + 1, - .pcie_ops = { - .is_enabled = en7523_pci_is_enabled, - .prepare = en7523_pci_prepare, -@@ -726,6 +726,8 @@ static const struct en_clk_soc_data en75 - }; - - static const struct en_clk_soc_data en7581_data = { -+ /* We increment num_clocks by 1 to account for additional PCIe clock */ -+ .num_clocks = ARRAY_SIZE(en7581_base_clks) + 1, - .pcie_ops = { - .is_enabled = en7581_pci_is_enabled, - .enable = en7581_pci_enable, diff --git a/target/linux/airoha/patches-6.12/041-02-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch b/target/linux/airoha/patches-6.12/041-02-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch deleted file mode 100644 index 5db79a47488..00000000000 --- a/target/linux/airoha/patches-6.12/041-02-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 02d3b7557ce28c373ea1e925ae16ab5988284313 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Jan 2025 00:10:03 +0100 -Subject: [PATCH 2/4] dt-bindings: clock: drop NUM_CLOCKS define for EN7581 - -Drop NUM_CLOCKS define for EN7581 include. This is not a binding and -should not be placed here. Value is derived internally in the user -driver. - -Signed-off-by: Christian Marangi -Acked-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20250113231030.6735-3-ansuelsmth@gmail.com -Signed-off-by: Stephen Boyd ---- - include/dt-bindings/clock/en7523-clk.h | 2 -- - 1 file changed, 2 deletions(-) - ---- a/include/dt-bindings/clock/en7523-clk.h -+++ b/include/dt-bindings/clock/en7523-clk.h -@@ -12,6 +12,4 @@ - #define EN7523_CLK_CRYPTO 6 - #define EN7523_CLK_PCIE 7 - --#define EN7523_NUM_CLOCKS 8 -- - #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ diff --git a/target/linux/airoha/patches-6.12/041-03-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch b/target/linux/airoha/patches-6.12/041-03-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch deleted file mode 100644 index a3f0c9e6fea..00000000000 --- a/target/linux/airoha/patches-6.12/041-03-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 82108ad3285f58f314ad41398f44017c7dbe44de Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Jan 2025 00:10:04 +0100 -Subject: [PATCH 3/4] dt-bindings: clock: add ID for eMMC for EN7581 - -Add ID for eMMC for EN7581. This is to control clock selection of eMMC -between 200MHz and 150MHz. - -Signed-off-by: Christian Marangi -Acked-by: Conor Dooley -Link: https://lore.kernel.org/r/20250113231030.6735-4-ansuelsmth@gmail.com -Signed-off-by: Stephen Boyd ---- - include/dt-bindings/clock/en7523-clk.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/include/dt-bindings/clock/en7523-clk.h -+++ b/include/dt-bindings/clock/en7523-clk.h -@@ -12,4 +12,6 @@ - #define EN7523_CLK_CRYPTO 6 - #define EN7523_CLK_PCIE 7 - -+#define EN7581_CLK_EMMC 8 -+ - #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ diff --git a/target/linux/airoha/patches-6.12/041-04-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch b/target/linux/airoha/patches-6.12/041-04-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch deleted file mode 100644 index 6c8a3300bee..00000000000 --- a/target/linux/airoha/patches-6.12/041-04-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch +++ /dev/null @@ -1,41 +0,0 @@ -From bfe257f9780d8f77045a7da6ec959ee0659d2f98 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Jan 2025 00:10:05 +0100 -Subject: [PATCH 4/4] clk: en7523: Add clock for eMMC for EN7581 - -Add clock for eMMC for EN7581. This is used to give info of the current -eMMC source clock and to switch it from 200MHz or 150MHz. - -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20250113231030.6735-5-ansuelsmth@gmail.com -Signed-off-by: Stephen Boyd ---- - drivers/clk/clk-en7523.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -91,6 +91,7 @@ static const u32 emi7581_base[] = { 5400 - static const u32 bus7581_base[] = { 600000000, 540000000 }; - static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; - static const u32 crypto_base[] = { 540000000, 480000000 }; -+static const u32 emmc7581_base[] = { 200000000, 150000000 }; - - static const struct en_clk_desc en7523_base_clks[] = { - { -@@ -281,6 +282,15 @@ static const struct en_clk_desc en7581_b - .base_shift = 0, - .base_values = crypto_base, - .n_base_values = ARRAY_SIZE(crypto_base), -+ }, { -+ .id = EN7581_CLK_EMMC, -+ .name = "emmc", -+ -+ .base_reg = REG_CRYPTO_CLKSRC2, -+ .base_bits = 1, -+ .base_shift = 12, -+ .base_values = emmc7581_base, -+ .n_base_values = ARRAY_SIZE(emmc7581_base), - } - }; - diff --git a/target/linux/airoha/patches-6.12/042-01-v6.14-PCI-mediatek-gen3-Rely-on-clk_bulk_prepare_enable-in.patch b/target/linux/airoha/patches-6.12/042-01-v6.14-PCI-mediatek-gen3-Rely-on-clk_bulk_prepare_enable-in.patch deleted file mode 100644 index c77ae7bfcae..00000000000 --- a/target/linux/airoha/patches-6.12/042-01-v6.14-PCI-mediatek-gen3-Rely-on-clk_bulk_prepare_enable-in.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0e7a622da17da0042294860cdb7a2fac091d25b1 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Jan 2025 10:50:40 +0100 -Subject: [PATCH 1/6] PCI: mediatek-gen3: Rely on clk_bulk_prepare_enable() in - mtk_pcie_en7581_power_up() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Replace clk_bulk_prepare() and clk_bulk_enable() with -clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up() routine. - -Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-1-21ac939a3b9b@kernel.org -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Krzysztof Wilczyński -Reviewed-by: AngeloGioacchino Del Regno -Reviewed-by: Manivannan Sadhasivam ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 14 +++----------- - 1 file changed, 3 insertions(+), 11 deletions(-) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -900,12 +900,6 @@ static int mtk_pcie_en7581_power_up(stru - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - -- err = clk_bulk_prepare(pcie->num_clks, pcie->clks); -- if (err) { -- dev_err(dev, "failed to prepare clock\n"); -- goto err_clk_prepare; -- } -- - val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | - FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | - FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | -@@ -918,17 +912,15 @@ static int mtk_pcie_en7581_power_up(stru - FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); - writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); - -- err = clk_bulk_enable(pcie->num_clks, pcie->clks); -+ err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks); - if (err) { - dev_err(dev, "failed to prepare clock\n"); -- goto err_clk_enable; -+ goto err_clk_prepare_enable; - } - - return 0; - --err_clk_enable: -- clk_bulk_unprepare(pcie->num_clks, pcie->clks); --err_clk_prepare: -+err_clk_prepare_enable: - pm_runtime_put_sync(dev); - pm_runtime_disable(dev); - reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); diff --git a/target/linux/airoha/patches-6.12/042-02-v6.14-PCI-mediatek-gen3-Move-reset-assert-callbacks-in-.po.patch b/target/linux/airoha/patches-6.12/042-02-v6.14-PCI-mediatek-gen3-Move-reset-assert-callbacks-in-.po.patch deleted file mode 100644 index f56a2ce7ebb..00000000000 --- a/target/linux/airoha/patches-6.12/042-02-v6.14-PCI-mediatek-gen3-Move-reset-assert-callbacks-in-.po.patch +++ /dev/null @@ -1,86 +0,0 @@ -From e4c7dfd953f7618f0ccb70d87c1629634f306fab Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Jan 2025 10:50:41 +0100 -Subject: [PATCH 2/6] PCI: mediatek-gen3: Move reset/assert callbacks in - .power_up() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In order to make the code more readable, the reset_control_bulk_assert() -function for PHY reset lines is moved to make it pair with -reset_control_bulk_deassert() in mtk_pcie_power_up() and -mtk_pcie_en7581_power_up(). The same change is done for -reset_control_assert() used to assert MAC reset line. - -Introduce PCIE_MTK_RESET_TIME_US macro for the time needed to -complete PCIe reset on MediaTek controller. - -Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-2-21ac939a3b9b@kernel.org -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Krzysztof Wilczyński -Reviewed-by: AngeloGioacchino Del Regno -Reviewed-by: Manivannan Sadhasivam ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 28 +++++++++++++-------- - 1 file changed, 18 insertions(+), 10 deletions(-) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -120,6 +120,8 @@ - - #define MAX_NUM_PHY_RESETS 3 - -+#define PCIE_MTK_RESET_TIME_US 10 -+ - /* Time in ms needed to complete PCIe reset on EN7581 SoC */ - #define PCIE_EN7581_RESET_TIME_MS 100 - -@@ -868,9 +870,14 @@ static int mtk_pcie_en7581_power_up(stru - u32 val; - - /* -- * Wait for the time needed to complete the bulk assert in -- * mtk_pcie_setup for EN7581 SoC. -+ * The controller may have been left out of reset by the bootloader -+ * so make sure that we get a clean start by asserting resets here. - */ -+ reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, -+ pcie->phy_resets); -+ reset_control_assert(pcie->mac_reset); -+ -+ /* Wait for the time needed to complete the reset lines assert. */ - mdelay(PCIE_EN7581_RESET_TIME_MS); - - err = phy_init(pcie->phy); -@@ -937,6 +944,15 @@ static int mtk_pcie_power_up(struct mtk_ - struct device *dev = pcie->dev; - int err; - -+ /* -+ * The controller may have been left out of reset by the bootloader -+ * so make sure that we get a clean start by asserting resets here. -+ */ -+ reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, -+ pcie->phy_resets); -+ reset_control_assert(pcie->mac_reset); -+ usleep_range(PCIE_MTK_RESET_TIME_US, 2 * PCIE_MTK_RESET_TIME_US); -+ - /* PHY power on and enable pipe clock */ - err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); - if (err) { -@@ -1009,14 +1025,6 @@ static int mtk_pcie_setup(struct mtk_gen - * counter since the bulk is shared. - */ - reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); -- /* -- * The controller may have been left out of reset by the bootloader -- * so make sure that we get a clean start by asserting resets here. -- */ -- reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets); -- -- reset_control_assert(pcie->mac_reset); -- usleep_range(10, 20); - - /* Don't touch the hardware registers before power up */ - err = pcie->soc->power_up(pcie); diff --git a/target/linux/airoha/patches-6.12/042-03-v6.14-PCI-mediatek-gen3-Add-comment-about-initialization-o.patch b/target/linux/airoha/patches-6.12/042-03-v6.14-PCI-mediatek-gen3-Add-comment-about-initialization-o.patch deleted file mode 100644 index 056d7733178..00000000000 --- a/target/linux/airoha/patches-6.12/042-03-v6.14-PCI-mediatek-gen3-Add-comment-about-initialization-o.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0c9d2d2ef0d916b490a9222ed20ff4616fca876d Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Jan 2025 10:50:42 +0100 -Subject: [PATCH 3/6] PCI: mediatek-gen3: Add comment about initialization - order in mtk_pcie_en7581_power_up() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a comment in mtk_pcie_en7581_power_up() to clarify, unlike the other -MediaTek Gen3 controllers, the Airoha EN7581 requires PHY initialization -and power-on before PHY reset deassert. - -Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-3-21ac939a3b9b@kernel.org -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Krzysztof Wilczyński -Reviewed-by: Manivannan Sadhasivam -Reviewed-by: AngeloGioacchino Del Regno ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -880,6 +880,10 @@ static int mtk_pcie_en7581_power_up(stru - /* Wait for the time needed to complete the reset lines assert. */ - mdelay(PCIE_EN7581_RESET_TIME_MS); - -+ /* -+ * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 -+ * requires PHY initialization and power-on before PHY reset deassert. -+ */ - err = phy_init(pcie->phy); - if (err) { - dev_err(dev, "failed to initialize PHY\n"); diff --git a/target/linux/airoha/patches-6.12/042-04-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch b/target/linux/airoha/patches-6.12/042-04-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch deleted file mode 100644 index 845209d58d8..00000000000 --- a/target/linux/airoha/patches-6.12/042-04-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 90d4e466c9ea2010f33880a36317a8486ccbe082 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Jan 2025 10:50:43 +0100 -Subject: [PATCH 4/6] PCI: mediatek-gen3: Move reset delay in - mtk_pcie_en7581_power_up() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal -causing occasional PCIe link down issues. In order to overcome the -problem, PCIe block is reset using REG_PCI_CONTROL (0x88) and -REG_RESET_CONTROL (0x834) registers available in the clock module -running clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up(). - -In order to make the code more readable, move the wait for the time -needed to complete the PCIe reset from en7581_pci_enable() to -mtk_pcie_en7581_power_up(). - -Reduce reset timeout from 250ms to the standard PCIE_T_PVPERL_MS value -(100ms) since it has no impact on the driver behavior. - -Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-4-21ac939a3b9b@kernel.org -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Krzysztof Wilczyński -Reviewed-by: AngeloGioacchino Del Regno -Reviewed-by: Manivannan Sadhasivam -Acked-by: Stephen Boyd ---- - drivers/clk/clk-en7523.c | 1 - - drivers/pci/controller/pcie-mediatek-gen3.c | 7 +++++++ - 2 files changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -489,7 +489,6 @@ static int en7581_pci_enable(struct clk_ - REG_PCI_CONTROL_PERSTOUT; - val = readl(np_base + REG_PCI_CONTROL); - writel(val | mask, np_base + REG_PCI_CONTROL); -- msleep(250); - - return 0; - } ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -929,6 +929,13 @@ static int mtk_pcie_en7581_power_up(stru - goto err_clk_prepare_enable; - } - -+ /* -+ * Airoha EN7581 performs PCIe reset via clk callbacks since it has a -+ * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to -+ * complete the PCIe reset. -+ */ -+ msleep(PCIE_T_PVPERL_MS); -+ - return 0; - - err_clk_prepare_enable: diff --git a/target/linux/airoha/patches-6.12/042-05-v6.14-PCI-mediatek-gen3-Rely-on-msleep-in-mtk_pcie_en7581_.patch b/target/linux/airoha/patches-6.12/042-05-v6.14-PCI-mediatek-gen3-Rely-on-msleep-in-mtk_pcie_en7581_.patch deleted file mode 100644 index 92a33a0afd8..00000000000 --- a/target/linux/airoha/patches-6.12/042-05-v6.14-PCI-mediatek-gen3-Rely-on-msleep-in-mtk_pcie_en7581_.patch +++ /dev/null @@ -1,41 +0,0 @@ -From c98bee18d0a094e37100c85effe5e161418f8644 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Jan 2025 10:50:44 +0100 -Subject: [PATCH 5/6] PCI: mediatek-gen3: Rely on msleep() in - mtk_pcie_en7581_power_up() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since mtk_pcie_en7581_power_up() runs in non-atomic context, rely on -msleep() routine instead of mdelay(). - -Link: https://lore.kernel.org/r/20250108-pcie-en7581-fixes-v6-5-21ac939a3b9b@kernel.org -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Krzysztof Wilczyński -Reviewed-by: AngeloGioacchino Del Regno -Reviewed-by: Manivannan Sadhasivam ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -878,7 +878,7 @@ static int mtk_pcie_en7581_power_up(stru - reset_control_assert(pcie->mac_reset); - - /* Wait for the time needed to complete the reset lines assert. */ -- mdelay(PCIE_EN7581_RESET_TIME_MS); -+ msleep(PCIE_EN7581_RESET_TIME_MS); - - /* - * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 -@@ -906,7 +906,7 @@ static int mtk_pcie_en7581_power_up(stru - * Wait for the time needed to complete the bulk de-assert above. - * This time is specific for EN7581 SoC. - */ -- mdelay(PCIE_EN7581_RESET_TIME_MS); -+ msleep(PCIE_EN7581_RESET_TIME_MS); - - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); diff --git a/target/linux/airoha/patches-6.12/042-06-v6.14-PCI-mediatek-gen3-Avoid-PCIe-resetting-via-PERST-for.patch b/target/linux/airoha/patches-6.12/042-06-v6.14-PCI-mediatek-gen3-Avoid-PCIe-resetting-via-PERST-for.patch deleted file mode 100644 index 080d5016987..00000000000 --- a/target/linux/airoha/patches-6.12/042-06-v6.14-PCI-mediatek-gen3-Avoid-PCIe-resetting-via-PERST-for.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 491cb9c5084790aafa02e843349492c284373231 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 9 Jan 2025 00:30:45 +0100 -Subject: [PATCH 6/6] PCI: mediatek-gen3: Avoid PCIe resetting via PERST# for - Airoha EN7581 SoC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Airoha EN7581 has a hw bug asserting/releasing PERST# signal causing -occasional PCIe link down issues. In order to overcome the problem, -PERST# signal is not asserted/released during device probe or -suspend/resume phase and the PCIe block is reset using -en7523_reset_assert() and en7581_pci_enable(). - -Introduce flags field in the mtk_gen3_pcie_pdata struct in order to -specify per-SoC capabilities. - -Link: https://lore.kernel.org/r/20250109-pcie-en7581-rst-fix-v4-1-4a45c89fb143@kernel.org -Tested-by: Hui Ma -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Krzysztof Wilczyński ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 59 ++++++++++++++------- - 1 file changed, 41 insertions(+), 18 deletions(-) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -127,10 +127,18 @@ - - struct mtk_gen3_pcie; - -+enum mtk_gen3_pcie_flags { -+ SKIP_PCIE_RSTB = BIT(0), /* Skip PERST# assertion during device -+ * probing or suspend/resume phase to -+ * avoid hw bugs/issues. -+ */ -+}; -+ - /** - * struct mtk_gen3_pcie_pdata - differentiate between host generations - * @power_up: pcie power_up callback - * @phy_resets: phy reset lines SoC data. -+ * @flags: pcie device flags. - */ - struct mtk_gen3_pcie_pdata { - int (*power_up)(struct mtk_gen3_pcie *pcie); -@@ -138,6 +146,7 @@ struct mtk_gen3_pcie_pdata { - const char *id[MAX_NUM_PHY_RESETS]; - int num_resets; - } phy_resets; -+ u32 flags; - }; - - /** -@@ -404,22 +413,33 @@ static int mtk_pcie_startup_port(struct - val |= PCIE_DISABLE_DVFSRC_VLT_REQ; - writel_relaxed(val, pcie->base + PCIE_MISC_CTRL_REG); - -- /* Assert all reset signals */ -- val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); -- val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB; -- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); -- - /* -- * Described in PCIe CEM specification sections 2.2 (PERST# Signal) -- * and 2.2.1 (Initial Power-Up (G3 to S0)). -- * The deassertion of PERST# should be delayed 100ms (TPVPERL) -- * for the power and clock to become stable. -+ * Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal -+ * causing occasional PCIe link down. In order to overcome the issue, -+ * PCIE_RSTB signals are not asserted/released at this stage and the -+ * PCIe block is reset using en7523_reset_assert() and -+ * en7581_pci_enable(). - */ -- msleep(100); -- -- /* De-assert reset signals */ -- val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB); -- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); -+ if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) { -+ /* Assert all reset signals */ -+ val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); -+ val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | -+ PCIE_PE_RSTB; -+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); -+ -+ /* -+ * Described in PCIe CEM specification revision 6.0. -+ * -+ * The deassertion of PERST# should be delayed 100ms (TPVPERL) -+ * for the power and clock to become stable. -+ */ -+ msleep(PCIE_T_PVPERL_MS); -+ -+ /* De-assert reset signals */ -+ val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | -+ PCIE_PE_RSTB); -+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); -+ } - - /* Check if the link is up or not */ - err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val, -@@ -1171,10 +1191,12 @@ static int mtk_pcie_suspend_noirq(struct - return err; - } - -- /* Pull down the PERST# pin */ -- val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); -- val |= PCIE_PE_RSTB; -- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); -+ if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) { -+ /* Assert the PERST# pin */ -+ val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG); -+ val |= PCIE_PE_RSTB; -+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG); -+ } - - dev_dbg(pcie->dev, "entered L2 states successfully"); - -@@ -1225,6 +1247,7 @@ static const struct mtk_gen3_pcie_pdata - .id[2] = "phy-lane2", - .num_resets = 3, - }, -+ .flags = SKIP_PCIE_RSTB, - }; - - static const struct of_device_id mtk_pcie_of_match[] = { diff --git a/target/linux/airoha/patches-6.12/043-v6.15-PCI-mediatek-gen3-Remove-leftover-mac_reset-assert-f.patch b/target/linux/airoha/patches-6.12/043-v6.15-PCI-mediatek-gen3-Remove-leftover-mac_reset-assert-f.patch deleted file mode 100644 index 7d7ee4aae1f..00000000000 --- a/target/linux/airoha/patches-6.12/043-v6.15-PCI-mediatek-gen3-Remove-leftover-mac_reset-assert-f.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b6d7bb0d3bd74b491e2e6fd59c4d5110d06fd63b Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 1 Feb 2025 12:00:18 +0100 -Subject: [PATCH] PCI: mediatek-gen3: Remove leftover mac_reset assert for - Airoha EN7581 SoC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove a leftover assert for mac_reset line in mtk_pcie_en7581_power_up(). - -This is not harmful since EN7581 does not requires mac_reset and -mac_reset is not defined in EN7581 device tree. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Manivannan Sadhasivam -Reviewed-by: Philipp Zabel -Link: https://lore.kernel.org/r/20250201-pcie-en7581-remove-mac_reset-v2-1-a06786cdc683@kernel.org -[kwilczynski: commit log] -Signed-off-by: Krzysztof Wilczyński ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -895,7 +895,6 @@ static int mtk_pcie_en7581_power_up(stru - */ - reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, - pcie->phy_resets); -- reset_control_assert(pcie->mac_reset); - - /* Wait for the time needed to complete the reset lines assert. */ - msleep(PCIE_EN7581_RESET_TIME_MS); diff --git a/target/linux/airoha/patches-6.12/044-v6.15-PCI-mediatek-gen3-Configure-PBUS_CSR-registers-for-E.patch b/target/linux/airoha/patches-6.12/044-v6.15-PCI-mediatek-gen3-Configure-PBUS_CSR-registers-for-E.patch deleted file mode 100644 index 4415eac0ee5..00000000000 --- a/target/linux/airoha/patches-6.12/044-v6.15-PCI-mediatek-gen3-Configure-PBUS_CSR-registers-for-E.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 249b78298078448a699c39356d27d8183af4b281 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Feb 2025 09:04:07 +0100 -Subject: [PATCH] PCI: mediatek-gen3: Configure PBUS_CSR registers for EN7581 - SoC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Configure PBus base address and address mask to allow the hw -to detect if a given address is accessible on PCIe controller. - -Fixes: f6ab898356dd ("PCI: mediatek-gen3: Add Airoha EN7581 support") -Reviewed-by: Manivannan Sadhasivam -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/20250225-en7581-pcie-pbus-csr-v4-2-24324382424a@kernel.org -Signed-off-by: Krzysztof Wilczyński ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 28 ++++++++++++++++++++- - 1 file changed, 27 insertions(+), 1 deletion(-) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -24,6 +25,7 @@ - #include - #include - #include -+#include - #include - - #include "../pci.h" -@@ -885,9 +887,13 @@ static int mtk_pcie_parse_port(struct mt - - static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie) - { -+ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); - struct device *dev = pcie->dev; -+ struct resource_entry *entry; -+ struct regmap *pbus_regmap; -+ u32 val, args[2], size; -+ resource_size_t addr; - int err; -- u32 val; - - /* - * The controller may have been left out of reset by the bootloader -@@ -900,6 +906,26 @@ static int mtk_pcie_en7581_power_up(stru - msleep(PCIE_EN7581_RESET_TIME_MS); - - /* -+ * Configure PBus base address and base address mask to allow the -+ * hw to detect if a given address is accessible on PCIe controller. -+ */ -+ pbus_regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, -+ "mediatek,pbus-csr", -+ ARRAY_SIZE(args), -+ args); -+ if (IS_ERR(pbus_regmap)) -+ return PTR_ERR(pbus_regmap); -+ -+ entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); -+ if (!entry) -+ return -ENODEV; -+ -+ addr = entry->res->start - entry->offset; -+ regmap_write(pbus_regmap, args[0], lower_32_bits(addr)); -+ size = lower_32_bits(resource_size(entry->res)); -+ regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); -+ -+ /* - * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 - * requires PHY initialization and power-on before PHY reset deassert. - */ diff --git a/target/linux/airoha/patches-6.12/046-v6.15-net-airoha-Fix-TSO-support-for-header-cloned-skbs.patch b/target/linux/airoha/patches-6.12/046-v6.15-net-airoha-Fix-TSO-support-for-header-cloned-skbs.patch deleted file mode 100644 index 894cc2c9c92..00000000000 --- a/target/linux/airoha/patches-6.12/046-v6.15-net-airoha-Fix-TSO-support-for-header-cloned-skbs.patch +++ /dev/null @@ -1,60 +0,0 @@ -From c6287e1a858e336cc202b484c6138a0fe252c6b3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 13 Feb 2025 16:34:20 +0100 -Subject: [PATCH] net: airoha: Fix TSO support for header cloned skbs - -For GSO packets, skb_cow_head() will reallocate the skb for TSO header -cloned skbs in airoha_dev_xmit(). For this reason, sinfo pointer can be -no more valid. Fix the issue relying on skb_shinfo() macro directly in -airoha_dev_xmit(). - -The problem exists since -commit 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC") -but it is not a user visible, since we can't currently enable TSO -for DSA user ports since we are missing to initialize net_device -vlan_features field. - -Reviewed-by: Mateusz Polchlopek -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250213-airoha-en7581-flowtable-offload-v4-1-b69ca16d74db@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -2569,11 +2569,10 @@ static u16 airoha_dev_select_queue(struc - static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, - struct net_device *dev) - { -- struct skb_shared_info *sinfo = skb_shinfo(skb); - struct airoha_gdm_port *port = netdev_priv(dev); -+ u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; - u32 msg0, msg1, len = skb_headlen(skb); - struct airoha_qdma *qdma = port->qdma; -- u32 nr_frags = 1 + sinfo->nr_frags; - struct netdev_queue *txq; - struct airoha_queue *q; - void *data = skb->data; -@@ -2596,8 +2595,9 @@ static netdev_tx_t airoha_dev_xmit(struc - if (skb_cow_head(skb, 0)) - goto error; - -- if (sinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { -- __be16 csum = cpu_to_be16(sinfo->gso_size); -+ if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | -+ SKB_GSO_TCPV6)) { -+ __be16 csum = cpu_to_be16(skb_shinfo(skb)->gso_size); - - tcp_hdr(skb)->check = (__force __sum16)csum; - msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1); -@@ -2626,7 +2626,7 @@ static netdev_tx_t airoha_dev_xmit(struc - for (i = 0; i < nr_frags; i++) { - struct airoha_qdma_desc *desc = &q->desc[index]; - struct airoha_queue_entry *e = &q->entry[index]; -- skb_frag_t *frag = &sinfo->frags[i]; -+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - dma_addr_t addr; - u32 val; - diff --git a/target/linux/airoha/patches-6.12/047-v6.13-net-airoha-Reset-BQL-stopping-the-netdevice.patch b/target/linux/airoha/patches-6.12/047-v6.13-net-airoha-Reset-BQL-stopping-the-netdevice.patch deleted file mode 100644 index ca73e019665..00000000000 --- a/target/linux/airoha/patches-6.12/047-v6.13-net-airoha-Reset-BQL-stopping-the-netdevice.patch +++ /dev/null @@ -1,42 +0,0 @@ -From c9f947769b77c8e8f318bfc8a0777e5d20c44d8d Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 17 Oct 2024 16:01:41 +0200 -Subject: [PATCH] net: airoha: Reset BQL stopping the netdevice - -Run airoha_qdma_cleanup_tx_queue() in ndo_stop callback in order to -unmap pending skbs. Moreover, reset BQL txq state stopping the netdevice, - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Hariprasad Kelam -Message-ID: <20241017-airoha-en7581-reset-bql-v1-1-08c0c9888de5@kernel.org> -Signed-off-by: Andrew Lunn ---- - drivers/net/ethernet/mediatek/airoha_eth.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ b/drivers/net/ethernet/mediatek/airoha_eth.c -@@ -2489,7 +2489,7 @@ static int airoha_dev_stop(struct net_de - { - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_qdma *qdma = port->qdma; -- int err; -+ int i, err; - - netif_tx_disable(dev); - err = airoha_set_gdm_ports(qdma->eth, false); -@@ -2500,6 +2500,14 @@ static int airoha_dev_stop(struct net_de - GLOBAL_CFG_TX_DMA_EN_MASK | - GLOBAL_CFG_RX_DMA_EN_MASK); - -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -+ if (!qdma->q_tx[i].ndesc) -+ continue; -+ -+ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -+ netdev_tx_reset_subqueue(dev, i); -+ } -+ - return 0; - } - diff --git a/target/linux/airoha/patches-6.12/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch b/target/linux/airoha/patches-6.12/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch deleted file mode 100644 index e3c54f1c045..00000000000 --- a/target/linux/airoha/patches-6.12/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch +++ /dev/null @@ -1,6863 +0,0 @@ -From fb3dda82fd38ca42140f29b3082324dcdc128293 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:09 +0100 -Subject: [PATCH 01/15] net: airoha: Move airoha_eth driver in a dedicated - folder - -The airoha_eth driver has no codebase shared with mtk_eth_soc one. -Moreover, the upcoming features (flowtable hw offloading, PCS, ..) will -not reuse any code from MediaTek driver. Move the Airoha driver in a -dedicated folder. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/Kconfig | 2 ++ - drivers/net/ethernet/Makefile | 1 + - drivers/net/ethernet/airoha/Kconfig | 18 ++++++++++++++++++ - drivers/net/ethernet/airoha/Makefile | 6 ++++++ - .../ethernet/{mediatek => airoha}/airoha_eth.c | 0 - drivers/net/ethernet/mediatek/Kconfig | 8 -------- - drivers/net/ethernet/mediatek/Makefile | 1 - - 7 files changed, 27 insertions(+), 9 deletions(-) - create mode 100644 drivers/net/ethernet/airoha/Kconfig - create mode 100644 drivers/net/ethernet/airoha/Makefile - rename drivers/net/ethernet/{mediatek => airoha}/airoha_eth.c (100%) - ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -20,6 +20,8 @@ source "drivers/net/ethernet/actions/Kco - source "drivers/net/ethernet/adaptec/Kconfig" - source "drivers/net/ethernet/aeroflex/Kconfig" - source "drivers/net/ethernet/agere/Kconfig" -+source "drivers/net/ethernet/airoha/Kconfig" -+source "drivers/net/ethernet/mellanox/Kconfig" - source "drivers/net/ethernet/alacritech/Kconfig" - source "drivers/net/ethernet/allwinner/Kconfig" - source "drivers/net/ethernet/alteon/Kconfig" ---- a/drivers/net/ethernet/Makefile -+++ b/drivers/net/ethernet/Makefile -@@ -10,6 +10,7 @@ obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adap - obj-$(CONFIG_GRETH) += aeroflex/ - obj-$(CONFIG_NET_VENDOR_ADI) += adi/ - obj-$(CONFIG_NET_VENDOR_AGERE) += agere/ -+obj-$(CONFIG_NET_VENDOR_AIROHA) += airoha/ - obj-$(CONFIG_NET_VENDOR_ALACRITECH) += alacritech/ - obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/ - obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ ---- /dev/null -+++ b/drivers/net/ethernet/airoha/Kconfig -@@ -0,0 +1,18 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config NET_VENDOR_AIROHA -+ bool "Airoha devices" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ help -+ If you have a Airoha SoC with ethernet, say Y. -+ -+if NET_VENDOR_AIROHA -+ -+config NET_AIROHA -+ tristate "Airoha SoC Gigabit Ethernet support" -+ depends on NET_DSA || !NET_DSA -+ select PAGE_POOL -+ help -+ This driver supports the gigabit ethernet MACs in the -+ Airoha SoC family. -+ -+endif #NET_VENDOR_AIROHA ---- /dev/null -+++ b/drivers/net/ethernet/airoha/Makefile -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+# -+# Airoha for the Mediatek SoCs built-in ethernet macs -+# -+ -+obj-$(CONFIG_NET_AIROHA) += airoha_eth.o ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -7,14 +7,6 @@ config NET_VENDOR_MEDIATEK - - if NET_VENDOR_MEDIATEK - --config NET_AIROHA -- tristate "Airoha SoC Gigabit Ethernet support" -- depends on NET_DSA || !NET_DSA -- select PAGE_POOL -- help -- This driver supports the gigabit ethernet MACs in the -- Airoha SoC family. -- - config NET_MEDIATEK_SOC_WED - depends on ARCH_MEDIATEK || COMPILE_TEST - def_bool NET_MEDIATEK_SOC != n ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -11,4 +11,3 @@ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) + - endif - obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o - obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o --obj-$(CONFIG_NET_AIROHA) += airoha_eth.o ---- /dev/null -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -0,0 +1,3378 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define AIROHA_MAX_NUM_GDM_PORTS 1 -+#define AIROHA_MAX_NUM_QDMA 2 -+#define AIROHA_MAX_NUM_RSTS 3 -+#define AIROHA_MAX_NUM_XSI_RSTS 5 -+#define AIROHA_MAX_MTU 2000 -+#define AIROHA_MAX_PACKET_SIZE 2048 -+#define AIROHA_NUM_QOS_CHANNELS 4 -+#define AIROHA_NUM_QOS_QUEUES 8 -+#define AIROHA_NUM_TX_RING 32 -+#define AIROHA_NUM_RX_RING 32 -+#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ -+ AIROHA_NUM_QOS_CHANNELS) -+#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 -+#define AIROHA_FE_MC_MAX_VLAN_PORT 16 -+#define AIROHA_NUM_TX_IRQ 2 -+#define HW_DSCP_NUM 2048 -+#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) -+#define TX_DSCP_NUM 1024 -+#define RX_DSCP_NUM(_n) \ -+ ((_n) == 2 ? 128 : \ -+ (_n) == 11 ? 128 : \ -+ (_n) == 15 ? 128 : \ -+ (_n) == 0 ? 1024 : 16) -+ -+#define PSE_RSV_PAGES 128 -+#define PSE_QUEUE_RSV_PAGES 64 -+ -+#define QDMA_METER_IDX(_n) ((_n) & 0xff) -+#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) -+ -+/* FE */ -+#define PSE_BASE 0x0100 -+#define CSR_IFC_BASE 0x0200 -+#define CDM1_BASE 0x0400 -+#define GDM1_BASE 0x0500 -+#define PPE1_BASE 0x0c00 -+ -+#define CDM2_BASE 0x1400 -+#define GDM2_BASE 0x1500 -+ -+#define GDM3_BASE 0x1100 -+#define GDM4_BASE 0x2500 -+ -+#define GDM_BASE(_n) \ -+ ((_n) == 4 ? GDM4_BASE : \ -+ (_n) == 3 ? GDM3_BASE : \ -+ (_n) == 2 ? GDM2_BASE : GDM1_BASE) -+ -+#define REG_FE_DMA_GLO_CFG 0x0000 -+#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) -+#define FE_DMA_GLO_PG_SZ_MASK BIT(3) -+ -+#define REG_FE_RST_GLO_CFG 0x0004 -+#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) -+#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) -+#define FE_RST_CORE_MASK BIT(0) -+ -+#define REG_FE_WAN_MAC_H 0x0030 -+#define REG_FE_LAN_MAC_H 0x0040 -+ -+#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) -+#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) -+ -+#define REG_FE_CDM1_OQ_MAP0 0x0050 -+#define REG_FE_CDM1_OQ_MAP1 0x0054 -+#define REG_FE_CDM1_OQ_MAP2 0x0058 -+#define REG_FE_CDM1_OQ_MAP3 0x005c -+ -+#define REG_FE_PCE_CFG 0x0070 -+#define PCE_DPI_EN_MASK BIT(2) -+#define PCE_KA_EN_MASK BIT(1) -+#define PCE_MC_EN_MASK BIT(0) -+ -+#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 -+#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) -+#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) -+#define PSE_CFG_WR_EN_MASK BIT(8) -+#define PSE_CFG_OQRSV_SEL_MASK BIT(0) -+ -+#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 -+#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) -+ -+#define PSE_FQ_CFG 0x008c -+#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) -+ -+#define REG_FE_PSE_BUF_SET 0x0090 -+#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) -+#define PSE_ALLRSV_MASK GENMASK(14, 0) -+ -+#define REG_PSE_SHARE_USED_THD 0x0094 -+#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) -+#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) -+ -+#define REG_GDM_MISC_CFG 0x0148 -+#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) -+#define GDM2_CHN_VLD_MODE_MASK BIT(5) -+ -+#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE -+#define FE_IFC_EN_MASK BIT(0) -+ -+#define REG_FE_VIP_PORT_EN 0x01f0 -+#define REG_FE_IFC_PORT_EN 0x01f4 -+ -+#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) -+#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) -+ -+#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) -+#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) -+#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) -+ -+#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) -+#define PATN_FCPU_EN_MASK BIT(7) -+#define PATN_SWP_EN_MASK BIT(6) -+#define PATN_DP_EN_MASK BIT(5) -+#define PATN_SP_EN_MASK BIT(4) -+#define PATN_TYPE_MASK GENMASK(3, 1) -+#define PATN_EN_MASK BIT(0) -+ -+#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) -+#define PATN_DP_MASK GENMASK(31, 16) -+#define PATN_SP_MASK GENMASK(15, 0) -+ -+#define REG_CDM1_VLAN_CTRL CDM1_BASE -+#define CDM1_VLAN_MASK GENMASK(31, 16) -+ -+#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) -+#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) -+ -+#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) -+#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ -+ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -+ -+#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) -+#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) -+#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) -+ -+#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) -+#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ -+ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -+ -+#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) -+#define GDM_DROP_CRC_ERR BIT(23) -+#define GDM_IP4_CKSUM BIT(22) -+#define GDM_TCP_CKSUM BIT(21) -+#define GDM_UDP_CKSUM BIT(20) -+#define GDM_UCFQ_MASK GENMASK(15, 12) -+#define GDM_BCFQ_MASK GENMASK(11, 8) -+#define GDM_MCFQ_MASK GENMASK(7, 4) -+#define GDM_OCFQ_MASK GENMASK(3, 0) -+ -+#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) -+#define GDM_INGRESS_FC_EN_MASK BIT(1) -+#define GDM_STAG_EN_MASK BIT(0) -+ -+#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) -+#define GDM_SHORT_LEN_MASK GENMASK(13, 0) -+#define GDM_LONG_LEN_MASK GENMASK(29, 16) -+ -+#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) -+#define FE_CPORT_PAD BIT(26) -+#define FE_CPORT_PORT_XFC_MASK BIT(25) -+#define FE_CPORT_QUEUE_XFC_MASK BIT(24) -+ -+#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) -+#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) -+#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) -+ -+#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) -+#define FE_STRICT_RFC2819_MODE_MASK BIT(31) -+#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) -+#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) -+#define FE_TX_MIB_ID_MASK GENMASK(15, 8) -+#define FE_RX_MIB_ID_MASK GENMASK(7, 0) -+ -+#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) -+#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) -+#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) -+#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) -+#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) -+#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) -+#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) -+#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) -+#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) -+#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) -+#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) -+#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) -+#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) -+#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) -+#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) -+ -+#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) -+#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) -+#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) -+#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) -+#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) -+#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) -+#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) -+#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) -+#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) -+#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) -+#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) -+#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) -+#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) -+#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) -+#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) -+#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) -+#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) -+#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) -+#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) -+#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) -+#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) -+#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) -+ -+#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) -+#define PPE1_SRAM_TABLE_EN_MASK BIT(0) -+#define PPE1_SRAM_HASH1_EN_MASK BIT(8) -+#define PPE1_DRAM_TABLE_EN_MASK BIT(16) -+#define PPE1_DRAM_HASH1_EN_MASK BIT(24) -+ -+#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) -+#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) -+#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) -+#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) -+ -+#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) -+#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) -+#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) -+#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) -+#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) -+#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) -+#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) -+#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) -+#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) -+#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) -+#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) -+#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) -+#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) -+#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) -+#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) -+#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) -+ -+#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) -+#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) -+#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) -+ -+#define REG_GDM3_FWD_CFG GDM3_BASE -+#define GDM3_PAD_EN_MASK BIT(28) -+ -+#define REG_GDM4_FWD_CFG GDM4_BASE -+#define GDM4_PAD_EN_MASK BIT(28) -+#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) -+ -+#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) -+#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) -+#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) -+#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) -+ -+#define REG_IP_FRAG_FP 0x2010 -+#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) -+#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) -+#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) -+#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) -+ -+#define REG_MC_VLAN_EN 0x2100 -+#define MC_VLAN_EN_MASK BIT(0) -+ -+#define REG_MC_VLAN_CFG 0x2104 -+#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) -+#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) -+#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) -+#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) -+#define MC_VLAN_CFG_RW_MASK BIT(0) -+ -+#define REG_MC_VLAN_DATA 0x2108 -+ -+#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 -+ -+/* QDMA */ -+#define REG_QDMA_GLOBAL_CFG 0x0004 -+#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) -+#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) -+#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) -+#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) -+#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) -+#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) -+#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) -+#define GLOBAL_CFG_RESET_MASK BIT(23) -+#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) -+#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) -+#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) -+#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) -+#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) -+#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) -+#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) -+#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) -+#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) -+#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) -+#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) -+#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) -+#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) -+#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) -+#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) -+ -+#define REG_FWD_DSCP_BASE 0x0010 -+#define REG_FWD_BUF_BASE 0x0014 -+ -+#define REG_HW_FWD_DSCP_CFG 0x0018 -+#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) -+#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) -+#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) -+ -+#define REG_INT_STATUS(_n) \ -+ (((_n) == 4) ? 0x0730 : \ -+ ((_n) == 3) ? 0x0724 : \ -+ ((_n) == 2) ? 0x0720 : \ -+ ((_n) == 1) ? 0x0024 : 0x0020) -+ -+#define REG_INT_ENABLE(_n) \ -+ (((_n) == 4) ? 0x0750 : \ -+ ((_n) == 3) ? 0x0744 : \ -+ ((_n) == 2) ? 0x0740 : \ -+ ((_n) == 1) ? 0x002c : 0x0028) -+ -+/* QDMA_CSR_INT_ENABLE1 */ -+#define RX15_COHERENT_INT_MASK BIT(31) -+#define RX14_COHERENT_INT_MASK BIT(30) -+#define RX13_COHERENT_INT_MASK BIT(29) -+#define RX12_COHERENT_INT_MASK BIT(28) -+#define RX11_COHERENT_INT_MASK BIT(27) -+#define RX10_COHERENT_INT_MASK BIT(26) -+#define RX9_COHERENT_INT_MASK BIT(25) -+#define RX8_COHERENT_INT_MASK BIT(24) -+#define RX7_COHERENT_INT_MASK BIT(23) -+#define RX6_COHERENT_INT_MASK BIT(22) -+#define RX5_COHERENT_INT_MASK BIT(21) -+#define RX4_COHERENT_INT_MASK BIT(20) -+#define RX3_COHERENT_INT_MASK BIT(19) -+#define RX2_COHERENT_INT_MASK BIT(18) -+#define RX1_COHERENT_INT_MASK BIT(17) -+#define RX0_COHERENT_INT_MASK BIT(16) -+#define TX7_COHERENT_INT_MASK BIT(15) -+#define TX6_COHERENT_INT_MASK BIT(14) -+#define TX5_COHERENT_INT_MASK BIT(13) -+#define TX4_COHERENT_INT_MASK BIT(12) -+#define TX3_COHERENT_INT_MASK BIT(11) -+#define TX2_COHERENT_INT_MASK BIT(10) -+#define TX1_COHERENT_INT_MASK BIT(9) -+#define TX0_COHERENT_INT_MASK BIT(8) -+#define CNT_OVER_FLOW_INT_MASK BIT(7) -+#define IRQ1_FULL_INT_MASK BIT(5) -+#define IRQ1_INT_MASK BIT(4) -+#define HWFWD_DSCP_LOW_INT_MASK BIT(3) -+#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) -+#define IRQ0_FULL_INT_MASK BIT(1) -+#define IRQ0_INT_MASK BIT(0) -+ -+#define TX_DONE_INT_MASK(_n) \ -+ ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ -+ : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -+ -+#define INT_TX_MASK \ -+ (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ -+ IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -+ -+#define INT_IDX0_MASK \ -+ (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ -+ TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ -+ TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ -+ TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ -+ RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ -+ RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ -+ RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ -+ RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ -+ RX15_COHERENT_INT_MASK | INT_TX_MASK) -+ -+/* QDMA_CSR_INT_ENABLE2 */ -+#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) -+#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) -+#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) -+#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) -+#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) -+#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) -+#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) -+#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) -+#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) -+#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) -+#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) -+#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) -+#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) -+#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) -+#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) -+#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) -+#define RX15_DONE_INT_MASK BIT(15) -+#define RX14_DONE_INT_MASK BIT(14) -+#define RX13_DONE_INT_MASK BIT(13) -+#define RX12_DONE_INT_MASK BIT(12) -+#define RX11_DONE_INT_MASK BIT(11) -+#define RX10_DONE_INT_MASK BIT(10) -+#define RX9_DONE_INT_MASK BIT(9) -+#define RX8_DONE_INT_MASK BIT(8) -+#define RX7_DONE_INT_MASK BIT(7) -+#define RX6_DONE_INT_MASK BIT(6) -+#define RX5_DONE_INT_MASK BIT(5) -+#define RX4_DONE_INT_MASK BIT(4) -+#define RX3_DONE_INT_MASK BIT(3) -+#define RX2_DONE_INT_MASK BIT(2) -+#define RX1_DONE_INT_MASK BIT(1) -+#define RX0_DONE_INT_MASK BIT(0) -+ -+#define RX_DONE_INT_MASK \ -+ (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ -+ RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ -+ RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ -+ RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ -+ RX15_DONE_INT_MASK) -+#define INT_IDX1_MASK \ -+ (RX_DONE_INT_MASK | \ -+ RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ -+ RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ -+ RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ -+ RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ -+ RX15_NO_CPU_DSCP_INT_MASK) -+ -+/* QDMA_CSR_INT_ENABLE5 */ -+#define TX31_COHERENT_INT_MASK BIT(31) -+#define TX30_COHERENT_INT_MASK BIT(30) -+#define TX29_COHERENT_INT_MASK BIT(29) -+#define TX28_COHERENT_INT_MASK BIT(28) -+#define TX27_COHERENT_INT_MASK BIT(27) -+#define TX26_COHERENT_INT_MASK BIT(26) -+#define TX25_COHERENT_INT_MASK BIT(25) -+#define TX24_COHERENT_INT_MASK BIT(24) -+#define TX23_COHERENT_INT_MASK BIT(23) -+#define TX22_COHERENT_INT_MASK BIT(22) -+#define TX21_COHERENT_INT_MASK BIT(21) -+#define TX20_COHERENT_INT_MASK BIT(20) -+#define TX19_COHERENT_INT_MASK BIT(19) -+#define TX18_COHERENT_INT_MASK BIT(18) -+#define TX17_COHERENT_INT_MASK BIT(17) -+#define TX16_COHERENT_INT_MASK BIT(16) -+#define TX15_COHERENT_INT_MASK BIT(15) -+#define TX14_COHERENT_INT_MASK BIT(14) -+#define TX13_COHERENT_INT_MASK BIT(13) -+#define TX12_COHERENT_INT_MASK BIT(12) -+#define TX11_COHERENT_INT_MASK BIT(11) -+#define TX10_COHERENT_INT_MASK BIT(10) -+#define TX9_COHERENT_INT_MASK BIT(9) -+#define TX8_COHERENT_INT_MASK BIT(8) -+ -+#define INT_IDX4_MASK \ -+ (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ -+ TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ -+ TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ -+ TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ -+ TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ -+ TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ -+ TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ -+ TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ -+ TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ -+ TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ -+ TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ -+ TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) -+ -+#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) -+ -+#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) -+#define TX_IRQ_THR_MASK GENMASK(27, 16) -+#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) -+ -+#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) -+#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) -+ -+#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) -+#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) -+#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) -+ -+#define REG_TX_RING_BASE(_n) \ -+ (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) -+ -+#define REG_TX_RING_BLOCKING(_n) \ -+ (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) -+ -+#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) -+#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) -+#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) -+#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) -+#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) -+ -+#define REG_TX_CPU_IDX(_n) \ -+ (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) -+ -+#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) -+ -+#define REG_TX_DMA_IDX(_n) \ -+ (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) -+ -+#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) -+ -+#define IRQ_RING_IDX_MASK GENMASK(20, 16) -+#define IRQ_DESC_IDX_MASK GENMASK(15, 0) -+ -+#define REG_RX_RING_BASE(_n) \ -+ (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) -+ -+#define REG_RX_RING_SIZE(_n) \ -+ (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) -+ -+#define RX_RING_THR_MASK GENMASK(31, 16) -+#define RX_RING_SIZE_MASK GENMASK(15, 0) -+ -+#define REG_RX_CPU_IDX(_n) \ -+ (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) -+ -+#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) -+ -+#define REG_RX_DMA_IDX(_n) \ -+ (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) -+ -+#define REG_RX_DELAY_INT_IDX(_n) \ -+ (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) -+ -+#define RX_DELAY_INT_MASK GENMASK(15, 0) -+ -+#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) -+ -+#define REG_INGRESS_TRTCM_CFG 0x0070 -+#define INGRESS_TRTCM_EN_MASK BIT(31) -+#define INGRESS_TRTCM_MODE_MASK BIT(30) -+#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) -+ -+#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) -+#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) -+ -+#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) -+#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) -+ -+#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) -+#define CNTR_EN_MASK BIT(31) -+#define CNTR_ALL_CHAN_EN_MASK BIT(30) -+#define CNTR_ALL_QUEUE_EN_MASK BIT(29) -+#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) -+#define CNTR_SRC_MASK GENMASK(27, 24) -+#define CNTR_DSCP_RING_MASK GENMASK(20, 16) -+#define CNTR_CHAN_MASK GENMASK(7, 3) -+#define CNTR_QUEUE_MASK GENMASK(2, 0) -+ -+#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) -+ -+#define REG_LMGR_INIT_CFG 0x1000 -+#define LMGR_INIT_START BIT(31) -+#define LMGR_SRAM_MODE_MASK BIT(30) -+#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) -+#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) -+ -+#define REG_FWD_DSCP_LOW_THR 0x1004 -+#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) -+ -+#define REG_EGRESS_RATE_METER_CFG 0x100c -+#define EGRESS_RATE_METER_EN_MASK BIT(31) -+#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) -+#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) -+#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) -+ -+#define REG_EGRESS_TRTCM_CFG 0x1010 -+#define EGRESS_TRTCM_EN_MASK BIT(31) -+#define EGRESS_TRTCM_MODE_MASK BIT(30) -+#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) -+ -+#define TRTCM_PARAM_RW_MASK BIT(31) -+#define TRTCM_PARAM_RW_DONE_MASK BIT(30) -+#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) -+#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) -+#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) -+#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) -+ -+#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) -+#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) -+#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) -+ -+#define REG_TXWRR_MODE_CFG 0x1020 -+#define TWRR_WEIGHT_SCALE_MASK BIT(31) -+#define TWRR_WEIGHT_BASE_MASK BIT(3) -+ -+#define REG_TXWRR_WEIGHT_CFG 0x1024 -+#define TWRR_RW_CMD_MASK BIT(31) -+#define TWRR_RW_CMD_DONE BIT(30) -+#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) -+#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) -+#define TWRR_VALUE_MASK GENMASK(15, 0) -+ -+#define REG_PSE_BUF_USAGE_CFG 0x1028 -+#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) -+ -+#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) -+#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) -+ -+#define REG_GLB_TRTCM_CFG 0x1080 -+#define GLB_TRTCM_EN_MASK BIT(31) -+#define GLB_TRTCM_MODE_MASK BIT(30) -+#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define GLB_FAST_TICK_MASK GENMASK(15, 0) -+ -+#define REG_TXQ_CNGST_CFG 0x10a0 -+#define TXQ_CNGST_DROP_EN BIT(31) -+#define TXQ_CNGST_DEI_DROP_EN BIT(30) -+ -+#define REG_SLA_TRTCM_CFG 0x1150 -+#define SLA_TRTCM_EN_MASK BIT(31) -+#define SLA_TRTCM_MODE_MASK BIT(30) -+#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define SLA_FAST_TICK_MASK GENMASK(15, 0) -+ -+/* CTRL */ -+#define QDMA_DESC_DONE_MASK BIT(31) -+#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ -+#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ -+#define QDMA_DESC_DEI_MASK BIT(25) -+#define QDMA_DESC_NO_DROP_MASK BIT(24) -+#define QDMA_DESC_LEN_MASK GENMASK(15, 0) -+/* DATA */ -+#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) -+/* TX MSG0 */ -+#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) -+#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) -+#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) -+#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) -+#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) -+#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) -+#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) -+#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) -+#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) -+#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) -+/* TX MSG1 */ -+#define QDMA_ETH_TXMSG_NO_DROP BIT(31) -+#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ -+#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) -+#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) -+#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) -+#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) -+#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) -+#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ -+#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ -+ -+/* RX MSG1 */ -+#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) -+#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) -+#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) -+#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) -+#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) -+#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) -+#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) -+#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) -+#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) -+ -+struct airoha_qdma_desc { -+ __le32 rsv; -+ __le32 ctrl; -+ __le32 addr; -+ __le32 data; -+ __le32 msg0; -+ __le32 msg1; -+ __le32 msg2; -+ __le32 msg3; -+}; -+ -+/* CTRL0 */ -+#define QDMA_FWD_DESC_CTX_MASK BIT(31) -+#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) -+#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) -+#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) -+/* CTRL1 */ -+#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) -+/* CTRL2 */ -+#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) -+ -+struct airoha_qdma_fwd_desc { -+ __le32 addr; -+ __le32 ctrl0; -+ __le32 ctrl1; -+ __le32 ctrl2; -+ __le32 msg0; -+ __le32 msg1; -+ __le32 rsv0; -+ __le32 rsv1; -+}; -+ -+enum { -+ QDMA_INT_REG_IDX0, -+ QDMA_INT_REG_IDX1, -+ QDMA_INT_REG_IDX2, -+ QDMA_INT_REG_IDX3, -+ QDMA_INT_REG_IDX4, -+ QDMA_INT_REG_MAX -+}; -+ -+enum { -+ XSI_PCIE0_PORT, -+ XSI_PCIE1_PORT, -+ XSI_USB_PORT, -+ XSI_AE_PORT, -+ XSI_ETH_PORT, -+}; -+ -+enum { -+ XSI_PCIE0_VIP_PORT_MASK = BIT(22), -+ XSI_PCIE1_VIP_PORT_MASK = BIT(23), -+ XSI_USB_VIP_PORT_MASK = BIT(25), -+ XSI_ETH_VIP_PORT_MASK = BIT(24), -+}; -+ -+enum { -+ DEV_STATE_INITIALIZED, -+}; -+ -+enum { -+ CDM_CRSN_QSEL_Q1 = 1, -+ CDM_CRSN_QSEL_Q5 = 5, -+ CDM_CRSN_QSEL_Q6 = 6, -+ CDM_CRSN_QSEL_Q15 = 15, -+}; -+ -+enum { -+ CRSN_08 = 0x8, -+ CRSN_21 = 0x15, /* KA */ -+ CRSN_22 = 0x16, /* hit bind and force route to CPU */ -+ CRSN_24 = 0x18, -+ CRSN_25 = 0x19, -+}; -+ -+enum { -+ FE_PSE_PORT_CDM1, -+ FE_PSE_PORT_GDM1, -+ FE_PSE_PORT_GDM2, -+ FE_PSE_PORT_GDM3, -+ FE_PSE_PORT_PPE1, -+ FE_PSE_PORT_CDM2, -+ FE_PSE_PORT_CDM3, -+ FE_PSE_PORT_CDM4, -+ FE_PSE_PORT_PPE2, -+ FE_PSE_PORT_GDM4, -+ FE_PSE_PORT_CDM5, -+ FE_PSE_PORT_DROP = 0xf, -+}; -+ -+enum tx_sched_mode { -+ TC_SCH_WRR8, -+ TC_SCH_SP, -+ TC_SCH_WRR7, -+ TC_SCH_WRR6, -+ TC_SCH_WRR5, -+ TC_SCH_WRR4, -+ TC_SCH_WRR3, -+ TC_SCH_WRR2, -+}; -+ -+enum trtcm_param_type { -+ TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ -+ TRTCM_TOKEN_RATE_MODE, -+ TRTCM_BUCKETSIZE_SHIFT_MODE, -+ TRTCM_BUCKET_COUNTER_MODE, -+}; -+ -+enum trtcm_mode_type { -+ TRTCM_COMMIT_MODE, -+ TRTCM_PEAK_MODE, -+}; -+ -+enum trtcm_param { -+ TRTCM_TICK_SEL = BIT(0), -+ TRTCM_PKT_MODE = BIT(1), -+ TRTCM_METER_MODE = BIT(2), -+}; -+ -+#define MIN_TOKEN_SIZE 4096 -+#define MAX_TOKEN_SIZE_OFFSET 17 -+#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) -+#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) -+ -+struct airoha_queue_entry { -+ union { -+ void *buf; -+ struct sk_buff *skb; -+ }; -+ dma_addr_t dma_addr; -+ u16 dma_len; -+}; -+ -+struct airoha_queue { -+ struct airoha_qdma *qdma; -+ -+ /* protect concurrent queue accesses */ -+ spinlock_t lock; -+ struct airoha_queue_entry *entry; -+ struct airoha_qdma_desc *desc; -+ u16 head; -+ u16 tail; -+ -+ int queued; -+ int ndesc; -+ int free_thr; -+ int buf_size; -+ -+ struct napi_struct napi; -+ struct page_pool *page_pool; -+}; -+ -+struct airoha_tx_irq_queue { -+ struct airoha_qdma *qdma; -+ -+ struct napi_struct napi; -+ -+ int size; -+ u32 *q; -+}; -+ -+struct airoha_hw_stats { -+ /* protect concurrent hw_stats accesses */ -+ spinlock_t lock; -+ struct u64_stats_sync syncp; -+ -+ /* get_stats64 */ -+ u64 rx_ok_pkts; -+ u64 tx_ok_pkts; -+ u64 rx_ok_bytes; -+ u64 tx_ok_bytes; -+ u64 rx_multicast; -+ u64 rx_errors; -+ u64 rx_drops; -+ u64 tx_drops; -+ u64 rx_crc_error; -+ u64 rx_over_errors; -+ /* ethtool stats */ -+ u64 tx_broadcast; -+ u64 tx_multicast; -+ u64 tx_len[7]; -+ u64 rx_broadcast; -+ u64 rx_fragment; -+ u64 rx_jabber; -+ u64 rx_len[7]; -+}; -+ -+struct airoha_qdma { -+ struct airoha_eth *eth; -+ void __iomem *regs; -+ -+ /* protect concurrent irqmask accesses */ -+ spinlock_t irq_lock; -+ u32 irqmask[QDMA_INT_REG_MAX]; -+ int irq; -+ -+ struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; -+ -+ struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; -+ struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; -+ -+ /* descriptor and packet buffers for qdma hw forward */ -+ struct { -+ void *desc; -+ void *q; -+ } hfwd; -+}; -+ -+struct airoha_gdm_port { -+ struct airoha_qdma *qdma; -+ struct net_device *dev; -+ int id; -+ -+ struct airoha_hw_stats stats; -+ -+ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); -+ -+ /* qos stats counters */ -+ u64 cpu_tx_packets; -+ u64 fwd_tx_packets; -+}; -+ -+struct airoha_eth { -+ struct device *dev; -+ -+ unsigned long state; -+ void __iomem *fe_regs; -+ -+ struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; -+ struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; -+ -+ struct net_device *napi_dev; -+ -+ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; -+ struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; -+}; -+ -+static u32 airoha_rr(void __iomem *base, u32 offset) -+{ -+ return readl(base + offset); -+} -+ -+static void airoha_wr(void __iomem *base, u32 offset, u32 val) -+{ -+ writel(val, base + offset); -+} -+ -+static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) -+{ -+ val |= (airoha_rr(base, offset) & ~mask); -+ airoha_wr(base, offset, val); -+ -+ return val; -+} -+ -+#define airoha_fe_rr(eth, offset) \ -+ airoha_rr((eth)->fe_regs, (offset)) -+#define airoha_fe_wr(eth, offset, val) \ -+ airoha_wr((eth)->fe_regs, (offset), (val)) -+#define airoha_fe_rmw(eth, offset, mask, val) \ -+ airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) -+#define airoha_fe_set(eth, offset, val) \ -+ airoha_rmw((eth)->fe_regs, (offset), 0, (val)) -+#define airoha_fe_clear(eth, offset, val) \ -+ airoha_rmw((eth)->fe_regs, (offset), (val), 0) -+ -+#define airoha_qdma_rr(qdma, offset) \ -+ airoha_rr((qdma)->regs, (offset)) -+#define airoha_qdma_wr(qdma, offset, val) \ -+ airoha_wr((qdma)->regs, (offset), (val)) -+#define airoha_qdma_rmw(qdma, offset, mask, val) \ -+ airoha_rmw((qdma)->regs, (offset), (mask), (val)) -+#define airoha_qdma_set(qdma, offset, val) \ -+ airoha_rmw((qdma)->regs, (offset), 0, (val)) -+#define airoha_qdma_clear(qdma, offset, val) \ -+ airoha_rmw((qdma)->regs, (offset), (val), 0) -+ -+static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, -+ u32 clear, u32 set) -+{ -+ unsigned long flags; -+ -+ if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask))) -+ return; -+ -+ spin_lock_irqsave(&qdma->irq_lock, flags); -+ -+ qdma->irqmask[index] &= ~clear; -+ qdma->irqmask[index] |= set; -+ airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]); -+ /* Read irq_enable register in order to guarantee the update above -+ * completes in the spinlock critical section. -+ */ -+ airoha_qdma_rr(qdma, REG_INT_ENABLE(index)); -+ -+ spin_unlock_irqrestore(&qdma->irq_lock, flags); -+} -+ -+static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index, -+ u32 mask) -+{ -+ airoha_qdma_set_irqmask(qdma, index, 0, mask); -+} -+ -+static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index, -+ u32 mask) -+{ -+ airoha_qdma_set_irqmask(qdma, index, mask, 0); -+} -+ -+static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) -+{ -+ /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. -+ * GDM{2,3,4} can be used as wan port connected to an external -+ * phy module. -+ */ -+ return port->id == 1; -+} -+ -+static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) -+{ -+ struct airoha_eth *eth = port->qdma->eth; -+ u32 val, reg; -+ -+ reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H -+ : REG_FE_WAN_MAC_H; -+ val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; -+ airoha_fe_wr(eth, reg, val); -+ -+ val = (addr[3] << 16) | (addr[4] << 8) | addr[5]; -+ airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); -+ airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); -+} -+ -+static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, -+ u32 val) -+{ -+ airoha_fe_rmw(eth, addr, GDM_OCFQ_MASK, -+ FIELD_PREP(GDM_OCFQ_MASK, val)); -+ airoha_fe_rmw(eth, addr, GDM_MCFQ_MASK, -+ FIELD_PREP(GDM_MCFQ_MASK, val)); -+ airoha_fe_rmw(eth, addr, GDM_BCFQ_MASK, -+ FIELD_PREP(GDM_BCFQ_MASK, val)); -+ airoha_fe_rmw(eth, addr, GDM_UCFQ_MASK, -+ FIELD_PREP(GDM_UCFQ_MASK, val)); -+} -+ -+static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) -+{ -+ u32 val = enable ? FE_PSE_PORT_PPE1 : FE_PSE_PORT_DROP; -+ u32 vip_port, cfg_addr; -+ -+ switch (port) { -+ case XSI_PCIE0_PORT: -+ vip_port = XSI_PCIE0_VIP_PORT_MASK; -+ cfg_addr = REG_GDM_FWD_CFG(3); -+ break; -+ case XSI_PCIE1_PORT: -+ vip_port = XSI_PCIE1_VIP_PORT_MASK; -+ cfg_addr = REG_GDM_FWD_CFG(3); -+ break; -+ case XSI_USB_PORT: -+ vip_port = XSI_USB_VIP_PORT_MASK; -+ cfg_addr = REG_GDM_FWD_CFG(4); -+ break; -+ case XSI_ETH_PORT: -+ vip_port = XSI_ETH_VIP_PORT_MASK; -+ cfg_addr = REG_GDM_FWD_CFG(4); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (enable) { -+ airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); -+ airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); -+ } else { -+ airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port); -+ airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); -+ } -+ -+ airoha_set_gdm_port_fwd_cfg(eth, cfg_addr, val); -+ -+ return 0; -+} -+ -+static int airoha_set_gdm_ports(struct airoha_eth *eth, bool enable) -+{ -+ const int port_list[] = { -+ XSI_PCIE0_PORT, -+ XSI_PCIE1_PORT, -+ XSI_USB_PORT, -+ XSI_ETH_PORT -+ }; -+ int i, err; -+ -+ for (i = 0; i < ARRAY_SIZE(port_list); i++) { -+ err = airoha_set_gdm_port(eth, port_list[i], enable); -+ if (err) -+ goto error; -+ } -+ -+ return 0; -+ -+error: -+ for (i--; i >= 0; i--) -+ airoha_set_gdm_port(eth, port_list[i], false); -+ -+ return err; -+} -+ -+static void airoha_fe_maccr_init(struct airoha_eth *eth) -+{ -+ int p; -+ -+ for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) { -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(p), -+ GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | -+ GDM_DROP_CRC_ERR); -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(p), -+ FE_PSE_PORT_CDM1); -+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), -+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -+ FIELD_PREP(GDM_LONG_LEN_MASK, 4004)); -+ } -+ -+ airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, -+ FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); -+ -+ airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); -+} -+ -+static void airoha_fe_vip_setup(struct airoha_eth *eth) -+{ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK); -+ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(4), -+ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -+ PATN_EN_MASK); -+ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(6), -+ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -+ PATN_EN_MASK); -+ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(7), -+ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -+ PATN_EN_MASK); -+ -+ /* BOOTP (0x43) */ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(8), -+ PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | -+ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -+ -+ /* BOOTP (0x44) */ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(9), -+ PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | -+ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -+ -+ /* ISAKMP */ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(10), -+ PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | -+ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -+ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(11), -+ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -+ PATN_EN_MASK); -+ -+ /* DHCPv6 */ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(12), -+ PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | -+ FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -+ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(19), -+ PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -+ PATN_EN_MASK); -+ -+ /* ETH->ETH_P_1905 (0x893a) */ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(20), -+ PATN_FCPU_EN_MASK | PATN_EN_MASK); -+ -+ airoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP); -+ airoha_fe_wr(eth, REG_FE_VIP_EN(21), -+ PATN_FCPU_EN_MASK | PATN_EN_MASK); -+} -+ -+static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth, -+ u32 port, u32 queue) -+{ -+ u32 val; -+ -+ airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, -+ PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK, -+ FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | -+ FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue)); -+ val = airoha_fe_rr(eth, REG_FE_PSE_QUEUE_CFG_VAL); -+ -+ return FIELD_GET(PSE_CFG_OQ_RSV_MASK, val); -+} -+ -+static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth, -+ u32 port, u32 queue, u32 val) -+{ -+ airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK, -+ FIELD_PREP(PSE_CFG_OQ_RSV_MASK, val)); -+ airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, -+ PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK | -+ PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK, -+ FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | -+ FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue) | -+ PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK); -+} -+ -+static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth) -+{ -+ u32 val = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET); -+ -+ return FIELD_GET(PSE_ALLRSV_MASK, val); -+} -+ -+static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth, -+ u32 port, u32 queue, u32 val) -+{ -+ u32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue); -+ u32 tmp, all_rsv, fq_limit; -+ -+ airoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val); -+ -+ /* modify all rsv */ -+ all_rsv = airoha_fe_get_pse_all_rsv(eth); -+ all_rsv += (val - orig_val); -+ airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK, -+ FIELD_PREP(PSE_ALLRSV_MASK, all_rsv)); -+ -+ /* modify hthd */ -+ tmp = airoha_fe_rr(eth, PSE_FQ_CFG); -+ fq_limit = FIELD_GET(PSE_FQ_LIMIT_MASK, tmp); -+ tmp = fq_limit - all_rsv - 0x20; -+ airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, -+ PSE_SHARE_USED_HTHD_MASK, -+ FIELD_PREP(PSE_SHARE_USED_HTHD_MASK, tmp)); -+ -+ tmp = fq_limit - all_rsv - 0x100; -+ airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, -+ PSE_SHARE_USED_MTHD_MASK, -+ FIELD_PREP(PSE_SHARE_USED_MTHD_MASK, tmp)); -+ tmp = (3 * tmp) >> 2; -+ airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, -+ PSE_SHARE_USED_LTHD_MASK, -+ FIELD_PREP(PSE_SHARE_USED_LTHD_MASK, tmp)); -+ -+ return 0; -+} -+ -+static void airoha_fe_pse_ports_init(struct airoha_eth *eth) -+{ -+ const u32 pse_port_num_queues[] = { -+ [FE_PSE_PORT_CDM1] = 6, -+ [FE_PSE_PORT_GDM1] = 6, -+ [FE_PSE_PORT_GDM2] = 32, -+ [FE_PSE_PORT_GDM3] = 6, -+ [FE_PSE_PORT_PPE1] = 4, -+ [FE_PSE_PORT_CDM2] = 6, -+ [FE_PSE_PORT_CDM3] = 8, -+ [FE_PSE_PORT_CDM4] = 10, -+ [FE_PSE_PORT_PPE2] = 4, -+ [FE_PSE_PORT_GDM4] = 2, -+ [FE_PSE_PORT_CDM5] = 2, -+ }; -+ u32 all_rsv; -+ int q; -+ -+ all_rsv = airoha_fe_get_pse_all_rsv(eth); -+ /* hw misses PPE2 oq rsv */ -+ all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; -+ airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); -+ -+ /* CMD1 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q, -+ PSE_QUEUE_RSV_PAGES); -+ /* GMD1 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM1]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q, -+ PSE_QUEUE_RSV_PAGES); -+ /* GMD2 */ -+ for (q = 6; q < pse_port_num_queues[FE_PSE_PORT_GDM2]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0); -+ /* GMD3 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM3]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q, -+ PSE_QUEUE_RSV_PAGES); -+ /* PPE1 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE1]; q++) { -+ if (q < pse_port_num_queues[FE_PSE_PORT_PPE1]) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, -+ PSE_QUEUE_RSV_PAGES); -+ else -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0); -+ } -+ /* CDM2 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM2]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q, -+ PSE_QUEUE_RSV_PAGES); -+ /* CDM3 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0); -+ /* CDM4 */ -+ for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, -+ PSE_QUEUE_RSV_PAGES); -+ /* PPE2 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { -+ if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, -+ PSE_QUEUE_RSV_PAGES); -+ else -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); -+ } -+ /* GMD4 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q, -+ PSE_QUEUE_RSV_PAGES); -+ /* CDM5 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM5]; q++) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q, -+ PSE_QUEUE_RSV_PAGES); -+} -+ -+static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < AIROHA_FE_MC_MAX_VLAN_TABLE; i++) { -+ int err, j; -+ u32 val; -+ -+ airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); -+ -+ val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | -+ MC_VLAN_CFG_TABLE_SEL_MASK | MC_VLAN_CFG_RW_MASK; -+ airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); -+ err = read_poll_timeout(airoha_fe_rr, val, -+ val & MC_VLAN_CFG_CMD_DONE_MASK, -+ USEC_PER_MSEC, 5 * USEC_PER_MSEC, -+ false, eth, REG_MC_VLAN_CFG); -+ if (err) -+ return err; -+ -+ for (j = 0; j < AIROHA_FE_MC_MAX_VLAN_PORT; j++) { -+ airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); -+ -+ val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | -+ FIELD_PREP(MC_VLAN_CFG_PORT_ID_MASK, j) | -+ MC_VLAN_CFG_RW_MASK; -+ airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); -+ err = read_poll_timeout(airoha_fe_rr, val, -+ val & MC_VLAN_CFG_CMD_DONE_MASK, -+ USEC_PER_MSEC, -+ 5 * USEC_PER_MSEC, false, eth, -+ REG_MC_VLAN_CFG); -+ if (err) -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) -+{ -+ /* CDM1_CRSN_QSEL */ -+ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_22 >> 2), -+ CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), -+ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), -+ CDM_CRSN_QSEL_Q1)); -+ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_08 >> 2), -+ CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), -+ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), -+ CDM_CRSN_QSEL_Q1)); -+ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_21 >> 2), -+ CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), -+ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), -+ CDM_CRSN_QSEL_Q1)); -+ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_24 >> 2), -+ CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), -+ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), -+ CDM_CRSN_QSEL_Q6)); -+ airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_25 >> 2), -+ CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), -+ FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), -+ CDM_CRSN_QSEL_Q1)); -+ /* CDM2_CRSN_QSEL */ -+ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_08 >> 2), -+ CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), -+ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), -+ CDM_CRSN_QSEL_Q1)); -+ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_21 >> 2), -+ CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), -+ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), -+ CDM_CRSN_QSEL_Q1)); -+ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_22 >> 2), -+ CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), -+ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), -+ CDM_CRSN_QSEL_Q1)); -+ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_24 >> 2), -+ CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), -+ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), -+ CDM_CRSN_QSEL_Q6)); -+ airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_25 >> 2), -+ CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), -+ FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), -+ CDM_CRSN_QSEL_Q1)); -+} -+ -+static int airoha_fe_init(struct airoha_eth *eth) -+{ -+ airoha_fe_maccr_init(eth); -+ -+ /* PSE IQ reserve */ -+ airoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK, -+ FIELD_PREP(PSE_IQ_RES1_P2_MASK, 0x10)); -+ airoha_fe_rmw(eth, REG_PSE_IQ_REV2, -+ PSE_IQ_RES2_P5_MASK | PSE_IQ_RES2_P4_MASK, -+ FIELD_PREP(PSE_IQ_RES2_P5_MASK, 0x40) | -+ FIELD_PREP(PSE_IQ_RES2_P4_MASK, 0x34)); -+ -+ /* enable FE copy engine for MC/KA/DPI */ -+ airoha_fe_wr(eth, REG_FE_PCE_CFG, -+ PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); -+ /* set vip queue selection to ring 1 */ -+ airoha_fe_rmw(eth, REG_CDM1_FWD_CFG, CDM1_VIP_QSEL_MASK, -+ FIELD_PREP(CDM1_VIP_QSEL_MASK, 0x4)); -+ airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_VIP_QSEL_MASK, -+ FIELD_PREP(CDM2_VIP_QSEL_MASK, 0x4)); -+ /* set GDM4 source interface offset to 8 */ -+ airoha_fe_rmw(eth, REG_GDM4_SRC_PORT_SET, -+ GDM4_SPORT_OFF2_MASK | -+ GDM4_SPORT_OFF1_MASK | -+ GDM4_SPORT_OFF0_MASK, -+ FIELD_PREP(GDM4_SPORT_OFF2_MASK, 8) | -+ FIELD_PREP(GDM4_SPORT_OFF1_MASK, 8) | -+ FIELD_PREP(GDM4_SPORT_OFF0_MASK, 8)); -+ -+ /* set PSE Page as 128B */ -+ airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, -+ FE_DMA_GLO_L2_SPACE_MASK | FE_DMA_GLO_PG_SZ_MASK, -+ FIELD_PREP(FE_DMA_GLO_L2_SPACE_MASK, 2) | -+ FE_DMA_GLO_PG_SZ_MASK); -+ airoha_fe_wr(eth, REG_FE_RST_GLO_CFG, -+ FE_RST_CORE_MASK | FE_RST_GDM3_MBI_ARB_MASK | -+ FE_RST_GDM4_MBI_ARB_MASK); -+ usleep_range(1000, 2000); -+ -+ /* connect RxRing1 and RxRing15 to PSE Port0 OQ-1 -+ * connect other rings to PSE Port0 OQ-0 -+ */ -+ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4)); -+ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28)); -+ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4)); -+ airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28)); -+ -+ airoha_fe_vip_setup(eth); -+ airoha_fe_pse_ports_init(eth); -+ -+ airoha_fe_set(eth, REG_GDM_MISC_CFG, -+ GDM2_RDM_ACK_WAIT_PREF_MASK | -+ GDM2_CHN_VLD_MODE_MASK); -+ airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, -+ FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); -+ -+ /* init fragment and assemble Force Port */ -+ /* NPU Core-3, NPU Bridge Channel-3 */ -+ airoha_fe_rmw(eth, REG_IP_FRAG_FP, -+ IP_FRAGMENT_PORT_MASK | IP_FRAGMENT_NBQ_MASK, -+ FIELD_PREP(IP_FRAGMENT_PORT_MASK, 6) | -+ FIELD_PREP(IP_FRAGMENT_NBQ_MASK, 3)); -+ /* QDMA LAN, RX Ring-22 */ -+ airoha_fe_rmw(eth, REG_IP_FRAG_FP, -+ IP_ASSEMBLE_PORT_MASK | IP_ASSEMBLE_NBQ_MASK, -+ FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | -+ FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); -+ -+ airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); -+ airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); -+ -+ airoha_fe_crsn_qsel_init(eth); -+ -+ airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK); -+ airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); -+ -+ /* default aging mode for mbi unlock issue */ -+ airoha_fe_rmw(eth, REG_GDM2_CHN_RLS, -+ MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, -+ FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | -+ FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); -+ -+ /* disable IFC by default */ -+ airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); -+ -+ /* enable 1:N vlan action, init vlan table */ -+ airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); -+ -+ return airoha_fe_mc_vlan_clear(eth); -+} -+ -+static int airoha_qdma_fill_rx_queue(struct airoha_queue *q) -+{ -+ enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); -+ struct airoha_qdma *qdma = q->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ int qid = q - &qdma->q_rx[0]; -+ int nframes = 0; -+ -+ while (q->queued < q->ndesc - 1) { -+ struct airoha_queue_entry *e = &q->entry[q->head]; -+ struct airoha_qdma_desc *desc = &q->desc[q->head]; -+ struct page *page; -+ int offset; -+ u32 val; -+ -+ page = page_pool_dev_alloc_frag(q->page_pool, &offset, -+ q->buf_size); -+ if (!page) -+ break; -+ -+ q->head = (q->head + 1) % q->ndesc; -+ q->queued++; -+ nframes++; -+ -+ e->buf = page_address(page) + offset; -+ e->dma_addr = page_pool_get_dma_addr(page) + offset; -+ e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); -+ -+ dma_sync_single_for_device(eth->dev, e->dma_addr, e->dma_len, -+ dir); -+ -+ val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); -+ WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); -+ WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr)); -+ val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, q->head); -+ WRITE_ONCE(desc->data, cpu_to_le32(val)); -+ WRITE_ONCE(desc->msg0, 0); -+ WRITE_ONCE(desc->msg1, 0); -+ WRITE_ONCE(desc->msg2, 0); -+ WRITE_ONCE(desc->msg3, 0); -+ -+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), -+ RX_RING_CPU_IDX_MASK, -+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); -+ } -+ -+ return nframes; -+} -+ -+static int airoha_qdma_get_gdm_port(struct airoha_eth *eth, -+ struct airoha_qdma_desc *desc) -+{ -+ u32 port, sport, msg1 = le32_to_cpu(desc->msg1); -+ -+ sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); -+ switch (sport) { -+ case 0x10 ... 0x13: -+ port = 0; -+ break; -+ case 0x2 ... 0x4: -+ port = sport - 1; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; -+} -+ -+static int airoha_qdma_rx_process(struct airoha_queue *q, int budget) -+{ -+ enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); -+ struct airoha_qdma *qdma = q->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ int qid = q - &qdma->q_rx[0]; -+ int done = 0; -+ -+ while (done < budget) { -+ struct airoha_queue_entry *e = &q->entry[q->tail]; -+ struct airoha_qdma_desc *desc = &q->desc[q->tail]; -+ dma_addr_t dma_addr = le32_to_cpu(desc->addr); -+ u32 desc_ctrl = le32_to_cpu(desc->ctrl); -+ struct sk_buff *skb; -+ int len, p; -+ -+ if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) -+ break; -+ -+ if (!dma_addr) -+ break; -+ -+ len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); -+ if (!len) -+ break; -+ -+ q->tail = (q->tail + 1) % q->ndesc; -+ q->queued--; -+ -+ dma_sync_single_for_cpu(eth->dev, dma_addr, -+ SKB_WITH_OVERHEAD(q->buf_size), dir); -+ -+ p = airoha_qdma_get_gdm_port(eth, desc); -+ if (p < 0 || !eth->ports[p]) { -+ page_pool_put_full_page(q->page_pool, -+ virt_to_head_page(e->buf), -+ true); -+ continue; -+ } -+ -+ skb = napi_build_skb(e->buf, q->buf_size); -+ if (!skb) { -+ page_pool_put_full_page(q->page_pool, -+ virt_to_head_page(e->buf), -+ true); -+ break; -+ } -+ -+ skb_reserve(skb, 2); -+ __skb_put(skb, len); -+ skb_mark_for_recycle(skb); -+ skb->dev = eth->ports[p]->dev; -+ skb->protocol = eth_type_trans(skb, skb->dev); -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ skb_record_rx_queue(skb, qid); -+ napi_gro_receive(&q->napi, skb); -+ -+ done++; -+ } -+ airoha_qdma_fill_rx_queue(q); -+ -+ return done; -+} -+ -+static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) -+{ -+ struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); -+ int cur, done = 0; -+ -+ do { -+ cur = airoha_qdma_rx_process(q, budget - done); -+ done += cur; -+ } while (cur && done < budget); -+ -+ if (done < budget && napi_complete(napi)) -+ airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1, -+ RX_DONE_INT_MASK); -+ -+ return done; -+} -+ -+static int airoha_qdma_init_rx_queue(struct airoha_queue *q, -+ struct airoha_qdma *qdma, int ndesc) -+{ -+ const struct page_pool_params pp_params = { -+ .order = 0, -+ .pool_size = 256, -+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, -+ .dma_dir = DMA_FROM_DEVICE, -+ .max_len = PAGE_SIZE, -+ .nid = NUMA_NO_NODE, -+ .dev = qdma->eth->dev, -+ .napi = &q->napi, -+ }; -+ struct airoha_eth *eth = qdma->eth; -+ int qid = q - &qdma->q_rx[0], thr; -+ dma_addr_t dma_addr; -+ -+ q->buf_size = PAGE_SIZE / 2; -+ q->qdma = qdma; -+ -+ q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry), -+ GFP_KERNEL); -+ if (!q->entry) -+ return -ENOMEM; -+ -+ q->desc = dmam_alloc_coherent(eth->dev, ndesc * sizeof(*q->desc), -+ &dma_addr, GFP_KERNEL); -+ if (!q->desc) -+ return -ENOMEM; -+ -+ q->page_pool = page_pool_create(&pp_params); -+ if (IS_ERR(q->page_pool)) { -+ int err = PTR_ERR(q->page_pool); -+ -+ q->page_pool = NULL; -+ return err; -+ } -+ -+ q->ndesc = ndesc; -+ netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll); -+ -+ airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr); -+ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), -+ RX_RING_SIZE_MASK, -+ FIELD_PREP(RX_RING_SIZE_MASK, ndesc)); -+ -+ thr = clamp(ndesc >> 3, 1, 32); -+ airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK, -+ FIELD_PREP(RX_RING_THR_MASK, thr)); -+ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, -+ FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); -+ -+ airoha_qdma_fill_rx_queue(q); -+ -+ return 0; -+} -+ -+static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q) -+{ -+ struct airoha_qdma *qdma = q->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ int qid = q - &qdma->q_rx[0]; -+ -+ while (q->queued) { -+ struct airoha_queue_entry *e = &q->entry[q->tail]; -+ struct airoha_qdma_desc *desc = &q->desc[q->tail]; -+ struct page *page = virt_to_head_page(e->buf); -+ -+ dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len, -+ page_pool_get_dma_dir(q->page_pool)); -+ page_pool_put_full_page(q->page_pool, page, false); -+ /* Reset DMA descriptor */ -+ WRITE_ONCE(desc->ctrl, 0); -+ WRITE_ONCE(desc->addr, 0); -+ WRITE_ONCE(desc->data, 0); -+ WRITE_ONCE(desc->msg0, 0); -+ WRITE_ONCE(desc->msg1, 0); -+ WRITE_ONCE(desc->msg2, 0); -+ WRITE_ONCE(desc->msg3, 0); -+ -+ q->tail = (q->tail + 1) % q->ndesc; -+ q->queued--; -+ } -+ -+ q->head = q->tail; -+ /* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is -+ * empty. -+ */ -+ airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK, -+ FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); -+ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, -+ FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail)); -+} -+ -+static int airoha_qdma_init_rx(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ int err; -+ -+ if (!(RX_DONE_INT_MASK & BIT(i))) { -+ /* rx-queue not binded to irq */ -+ continue; -+ } -+ -+ err = airoha_qdma_init_rx_queue(&qdma->q_rx[i], qdma, -+ RX_DSCP_NUM(i)); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget) -+{ -+ struct airoha_tx_irq_queue *irq_q; -+ int id, done = 0, irq_queued; -+ struct airoha_qdma *qdma; -+ struct airoha_eth *eth; -+ u32 status, head; -+ -+ irq_q = container_of(napi, struct airoha_tx_irq_queue, napi); -+ qdma = irq_q->qdma; -+ id = irq_q - &qdma->q_tx_irq[0]; -+ eth = qdma->eth; -+ -+ status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(id)); -+ head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); -+ head = head % irq_q->size; -+ irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); -+ -+ while (irq_queued > 0 && done < budget) { -+ u32 qid, val = irq_q->q[head]; -+ struct airoha_qdma_desc *desc; -+ struct airoha_queue_entry *e; -+ struct airoha_queue *q; -+ u32 index, desc_ctrl; -+ struct sk_buff *skb; -+ -+ if (val == 0xff) -+ break; -+ -+ irq_q->q[head] = 0xff; /* mark as done */ -+ head = (head + 1) % irq_q->size; -+ irq_queued--; -+ done++; -+ -+ qid = FIELD_GET(IRQ_RING_IDX_MASK, val); -+ if (qid >= ARRAY_SIZE(qdma->q_tx)) -+ continue; -+ -+ q = &qdma->q_tx[qid]; -+ if (!q->ndesc) -+ continue; -+ -+ index = FIELD_GET(IRQ_DESC_IDX_MASK, val); -+ if (index >= q->ndesc) -+ continue; -+ -+ spin_lock_bh(&q->lock); -+ -+ if (!q->queued) -+ goto unlock; -+ -+ desc = &q->desc[index]; -+ desc_ctrl = le32_to_cpu(desc->ctrl); -+ -+ if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && -+ !(desc_ctrl & QDMA_DESC_DROP_MASK)) -+ goto unlock; -+ -+ e = &q->entry[index]; -+ skb = e->skb; -+ -+ dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, -+ DMA_TO_DEVICE); -+ memset(e, 0, sizeof(*e)); -+ WRITE_ONCE(desc->msg0, 0); -+ WRITE_ONCE(desc->msg1, 0); -+ q->queued--; -+ -+ /* completion ring can report out-of-order indexes if hw QoS -+ * is enabled and packets with different priority are queued -+ * to same DMA ring. Take into account possible out-of-order -+ * reports incrementing DMA ring tail pointer -+ */ -+ while (q->tail != q->head && !q->entry[q->tail].dma_addr) -+ q->tail = (q->tail + 1) % q->ndesc; -+ -+ if (skb) { -+ u16 queue = skb_get_queue_mapping(skb); -+ struct netdev_queue *txq; -+ -+ txq = netdev_get_tx_queue(skb->dev, queue); -+ netdev_tx_completed_queue(txq, 1, skb->len); -+ if (netif_tx_queue_stopped(txq) && -+ q->ndesc - q->queued >= q->free_thr) -+ netif_tx_wake_queue(txq); -+ -+ dev_kfree_skb_any(skb); -+ } -+unlock: -+ spin_unlock_bh(&q->lock); -+ } -+ -+ if (done) { -+ int i, len = done >> 7; -+ -+ for (i = 0; i < len; i++) -+ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), -+ IRQ_CLEAR_LEN_MASK, 0x80); -+ airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), -+ IRQ_CLEAR_LEN_MASK, (done & 0x7f)); -+ } -+ -+ if (done < budget && napi_complete(napi)) -+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, -+ TX_DONE_INT_MASK(id)); -+ -+ return done; -+} -+ -+static int airoha_qdma_init_tx_queue(struct airoha_queue *q, -+ struct airoha_qdma *qdma, int size) -+{ -+ struct airoha_eth *eth = qdma->eth; -+ int i, qid = q - &qdma->q_tx[0]; -+ dma_addr_t dma_addr; -+ -+ spin_lock_init(&q->lock); -+ q->ndesc = size; -+ q->qdma = qdma; -+ q->free_thr = 1 + MAX_SKB_FRAGS; -+ -+ q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), -+ GFP_KERNEL); -+ if (!q->entry) -+ return -ENOMEM; -+ -+ q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), -+ &dma_addr, GFP_KERNEL); -+ if (!q->desc) -+ return -ENOMEM; -+ -+ for (i = 0; i < q->ndesc; i++) { -+ u32 val; -+ -+ val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); -+ WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); -+ } -+ -+ /* xmit ring drop default setting */ -+ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), -+ TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK); -+ -+ airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); -+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, -+ FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); -+ airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, -+ FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head)); -+ -+ return 0; -+} -+ -+static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q, -+ struct airoha_qdma *qdma, int size) -+{ -+ int id = irq_q - &qdma->q_tx_irq[0]; -+ struct airoha_eth *eth = qdma->eth; -+ dma_addr_t dma_addr; -+ -+ netif_napi_add_tx(eth->napi_dev, &irq_q->napi, -+ airoha_qdma_tx_napi_poll); -+ irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32), -+ &dma_addr, GFP_KERNEL); -+ if (!irq_q->q) -+ return -ENOMEM; -+ -+ memset(irq_q->q, 0xff, size * sizeof(u32)); -+ irq_q->size = size; -+ irq_q->qdma = qdma; -+ -+ airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr); -+ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK, -+ FIELD_PREP(TX_IRQ_DEPTH_MASK, size)); -+ airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK, -+ FIELD_PREP(TX_IRQ_THR_MASK, 1)); -+ -+ return 0; -+} -+ -+static int airoha_qdma_init_tx(struct airoha_qdma *qdma) -+{ -+ int i, err; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { -+ err = airoha_qdma_tx_irq_init(&qdma->q_tx_irq[i], qdma, -+ IRQ_QUEUE_LEN(i)); -+ if (err) -+ return err; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -+ err = airoha_qdma_init_tx_queue(&qdma->q_tx[i], qdma, -+ TX_DSCP_NUM); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) -+{ -+ struct airoha_eth *eth = q->qdma->eth; -+ -+ spin_lock_bh(&q->lock); -+ while (q->queued) { -+ struct airoha_queue_entry *e = &q->entry[q->tail]; -+ -+ dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, -+ DMA_TO_DEVICE); -+ dev_kfree_skb_any(e->skb); -+ e->skb = NULL; -+ -+ q->tail = (q->tail + 1) % q->ndesc; -+ q->queued--; -+ } -+ spin_unlock_bh(&q->lock); -+} -+ -+static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) -+{ -+ struct airoha_eth *eth = qdma->eth; -+ dma_addr_t dma_addr; -+ u32 status; -+ int size; -+ -+ size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); -+ qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr, -+ GFP_KERNEL); -+ if (!qdma->hfwd.desc) -+ return -ENOMEM; -+ -+ airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); -+ -+ size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; -+ qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr, -+ GFP_KERNEL); -+ if (!qdma->hfwd.q) -+ return -ENOMEM; -+ -+ airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); -+ -+ airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, -+ HW_FWD_DSCP_PAYLOAD_SIZE_MASK, -+ FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); -+ airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK, -+ FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128)); -+ airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, -+ LMGR_INIT_START | LMGR_SRAM_MODE_MASK | -+ HW_FWD_DESC_NUM_MASK, -+ FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | -+ LMGR_INIT_START); -+ -+ return read_poll_timeout(airoha_qdma_rr, status, -+ !(status & LMGR_INIT_START), USEC_PER_MSEC, -+ 30 * USEC_PER_MSEC, true, qdma, -+ REG_LMGR_INIT_CFG); -+} -+ -+static void airoha_qdma_init_qos(struct airoha_qdma *qdma) -+{ -+ airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK); -+ airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK); -+ -+ airoha_qdma_clear(qdma, REG_PSE_BUF_USAGE_CFG, -+ PSE_BUF_ESTIMATE_EN_MASK); -+ -+ airoha_qdma_set(qdma, REG_EGRESS_RATE_METER_CFG, -+ EGRESS_RATE_METER_EN_MASK | -+ EGRESS_RATE_METER_EQ_RATE_EN_MASK); -+ /* 2047us x 31 = 63.457ms */ -+ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, -+ EGRESS_RATE_METER_WINDOW_SZ_MASK, -+ FIELD_PREP(EGRESS_RATE_METER_WINDOW_SZ_MASK, 0x1f)); -+ airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, -+ EGRESS_RATE_METER_TIMESLICE_MASK, -+ FIELD_PREP(EGRESS_RATE_METER_TIMESLICE_MASK, 0x7ff)); -+ -+ /* ratelimit init */ -+ airoha_qdma_set(qdma, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK); -+ /* fast-tick 25us */ -+ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK, -+ FIELD_PREP(GLB_FAST_TICK_MASK, 25)); -+ airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK, -+ FIELD_PREP(GLB_SLOW_TICK_RATIO_MASK, 40)); -+ -+ airoha_qdma_set(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK); -+ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK, -+ FIELD_PREP(EGRESS_FAST_TICK_MASK, 25)); -+ airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, -+ EGRESS_SLOW_TICK_RATIO_MASK, -+ FIELD_PREP(EGRESS_SLOW_TICK_RATIO_MASK, 40)); -+ -+ airoha_qdma_set(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK); -+ airoha_qdma_clear(qdma, REG_INGRESS_TRTCM_CFG, -+ INGRESS_TRTCM_MODE_MASK); -+ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK, -+ FIELD_PREP(INGRESS_FAST_TICK_MASK, 125)); -+ airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, -+ INGRESS_SLOW_TICK_RATIO_MASK, -+ FIELD_PREP(INGRESS_SLOW_TICK_RATIO_MASK, 8)); -+ -+ airoha_qdma_set(qdma, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK); -+ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK, -+ FIELD_PREP(SLA_FAST_TICK_MASK, 25)); -+ airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK, -+ FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40)); -+} -+ -+static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ for (i = 0; i < AIROHA_NUM_QOS_CHANNELS; i++) { -+ /* Tx-cpu transferred count */ -+ airoha_qdma_wr(qdma, REG_CNTR_VAL(i << 1), 0); -+ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), -+ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | -+ CNTR_ALL_DSCP_RING_EN_MASK | -+ FIELD_PREP(CNTR_CHAN_MASK, i)); -+ /* Tx-fwd transferred count */ -+ airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0); -+ airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), -+ CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | -+ CNTR_ALL_DSCP_RING_EN_MASK | -+ FIELD_PREP(CNTR_SRC_MASK, 1) | -+ FIELD_PREP(CNTR_CHAN_MASK, i)); -+ } -+} -+ -+static int airoha_qdma_hw_init(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ /* clear pending irqs */ -+ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) -+ airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); -+ -+ /* setup irqs */ -+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK); -+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK); -+ airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK); -+ -+ /* setup irq binding */ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -+ if (!qdma->q_tx[i].ndesc) -+ continue; -+ -+ if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i)) -+ airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(i), -+ TX_RING_IRQ_BLOCKING_CFG_MASK); -+ else -+ airoha_qdma_clear(qdma, REG_TX_RING_BLOCKING(i), -+ TX_RING_IRQ_BLOCKING_CFG_MASK); -+ } -+ -+ airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG, -+ GLOBAL_CFG_RX_2B_OFFSET_MASK | -+ FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) | -+ GLOBAL_CFG_CPU_TXR_RR_MASK | -+ GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK | -+ GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK | -+ GLOBAL_CFG_MULTICAST_EN_MASK | -+ GLOBAL_CFG_IRQ0_EN_MASK | GLOBAL_CFG_IRQ1_EN_MASK | -+ GLOBAL_CFG_TX_WB_DONE_MASK | -+ FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2)); -+ -+ airoha_qdma_init_qos(qdma); -+ -+ /* disable qdma rx delay interrupt */ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ airoha_qdma_clear(qdma, REG_RX_DELAY_INT_IDX(i), -+ RX_DELAY_INT_MASK); -+ } -+ -+ airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG, -+ TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN); -+ airoha_qdma_init_qos_stats(qdma); -+ -+ return 0; -+} -+ -+static irqreturn_t airoha_irq_handler(int irq, void *dev_instance) -+{ -+ struct airoha_qdma *qdma = dev_instance; -+ u32 intr[ARRAY_SIZE(qdma->irqmask)]; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) { -+ intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i)); -+ intr[i] &= qdma->irqmask[i]; -+ airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]); -+ } -+ -+ if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state)) -+ return IRQ_NONE; -+ -+ if (intr[1] & RX_DONE_INT_MASK) { -+ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1, -+ RX_DONE_INT_MASK); -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ if (intr[1] & BIT(i)) -+ napi_schedule(&qdma->q_rx[i].napi); -+ } -+ } -+ -+ if (intr[0] & INT_TX_MASK) { -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { -+ if (!(intr[0] & TX_DONE_INT_MASK(i))) -+ continue; -+ -+ airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, -+ TX_DONE_INT_MASK(i)); -+ napi_schedule(&qdma->q_tx_irq[i].napi); -+ } -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int airoha_qdma_init(struct platform_device *pdev, -+ struct airoha_eth *eth, -+ struct airoha_qdma *qdma) -+{ -+ int err, id = qdma - ð->qdma[0]; -+ const char *res; -+ -+ spin_lock_init(&qdma->irq_lock); -+ qdma->eth = eth; -+ -+ res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id); -+ if (!res) -+ return -ENOMEM; -+ -+ qdma->regs = devm_platform_ioremap_resource_byname(pdev, res); -+ if (IS_ERR(qdma->regs)) -+ return dev_err_probe(eth->dev, PTR_ERR(qdma->regs), -+ "failed to iomap qdma%d regs\n", id); -+ -+ qdma->irq = platform_get_irq(pdev, 4 * id); -+ if (qdma->irq < 0) -+ return qdma->irq; -+ -+ err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler, -+ IRQF_SHARED, KBUILD_MODNAME, qdma); -+ if (err) -+ return err; -+ -+ err = airoha_qdma_init_rx(qdma); -+ if (err) -+ return err; -+ -+ err = airoha_qdma_init_tx(qdma); -+ if (err) -+ return err; -+ -+ err = airoha_qdma_init_hfwd_queues(qdma); -+ if (err) -+ return err; -+ -+ return airoha_qdma_hw_init(qdma); -+} -+ -+static int airoha_hw_init(struct platform_device *pdev, -+ struct airoha_eth *eth) -+{ -+ int err, i; -+ -+ /* disable xsi */ -+ err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), -+ eth->xsi_rsts); -+ if (err) -+ return err; -+ -+ err = reset_control_bulk_assert(ARRAY_SIZE(eth->rsts), eth->rsts); -+ if (err) -+ return err; -+ -+ msleep(20); -+ err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts); -+ if (err) -+ return err; -+ -+ msleep(20); -+ err = airoha_fe_init(eth); -+ if (err) -+ return err; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { -+ err = airoha_qdma_init(pdev, eth, ð->qdma[i]); -+ if (err) -+ return err; -+ } -+ -+ set_bit(DEV_STATE_INITIALIZED, ð->state); -+ -+ return 0; -+} -+ -+static void airoha_hw_cleanup(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ netif_napi_del(&qdma->q_rx[i].napi); -+ airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); -+ if (qdma->q_rx[i].page_pool) -+ page_pool_destroy(qdma->q_rx[i].page_pool); -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -+ netif_napi_del(&qdma->q_tx_irq[i].napi); -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -+ if (!qdma->q_tx[i].ndesc) -+ continue; -+ -+ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -+ } -+} -+ -+static void airoha_qdma_start_napi(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -+ napi_enable(&qdma->q_tx_irq[i].napi); -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ napi_enable(&qdma->q_rx[i].napi); -+ } -+} -+ -+static void airoha_qdma_stop_napi(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -+ napi_disable(&qdma->q_tx_irq[i].napi); -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ napi_disable(&qdma->q_rx[i].napi); -+ } -+} -+ -+static void airoha_update_hw_stats(struct airoha_gdm_port *port) -+{ -+ struct airoha_eth *eth = port->qdma->eth; -+ u32 val, i = 0; -+ -+ spin_lock(&port->stats.lock); -+ u64_stats_update_begin(&port->stats.syncp); -+ -+ /* TX */ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id)); -+ port->stats.tx_ok_pkts += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id)); -+ port->stats.tx_ok_pkts += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id)); -+ port->stats.tx_ok_bytes += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id)); -+ port->stats.tx_ok_bytes += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id)); -+ port->stats.tx_drops += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id)); -+ port->stats.tx_broadcast += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id)); -+ port->stats.tx_multicast += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id)); -+ port->stats.tx_len[i] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id)); -+ port->stats.tx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id)); -+ port->stats.tx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id)); -+ port->stats.tx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id)); -+ port->stats.tx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id)); -+ port->stats.tx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id)); -+ port->stats.tx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id)); -+ port->stats.tx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id)); -+ port->stats.tx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id)); -+ port->stats.tx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id)); -+ port->stats.tx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id)); -+ port->stats.tx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id)); -+ port->stats.tx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id)); -+ port->stats.tx_len[i++] += val; -+ -+ /* RX */ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id)); -+ port->stats.rx_ok_pkts += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id)); -+ port->stats.rx_ok_pkts += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id)); -+ port->stats.rx_ok_bytes += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id)); -+ port->stats.rx_ok_bytes += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id)); -+ port->stats.rx_drops += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id)); -+ port->stats.rx_broadcast += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id)); -+ port->stats.rx_multicast += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id)); -+ port->stats.rx_errors += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id)); -+ port->stats.rx_crc_error += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id)); -+ port->stats.rx_over_errors += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id)); -+ port->stats.rx_fragment += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id)); -+ port->stats.rx_jabber += val; -+ -+ i = 0; -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id)); -+ port->stats.rx_len[i] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id)); -+ port->stats.rx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id)); -+ port->stats.rx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id)); -+ port->stats.rx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id)); -+ port->stats.rx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id)); -+ port->stats.rx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id)); -+ port->stats.rx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id)); -+ port->stats.rx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id)); -+ port->stats.rx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id)); -+ port->stats.rx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id)); -+ port->stats.rx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id)); -+ port->stats.rx_len[i] += ((u64)val << 32); -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id)); -+ port->stats.rx_len[i++] += val; -+ -+ val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id)); -+ port->stats.rx_len[i++] += val; -+ -+ /* reset mib counters */ -+ airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id), -+ FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK); -+ -+ u64_stats_update_end(&port->stats.syncp); -+ spin_unlock(&port->stats.lock); -+} -+ -+static int airoha_dev_open(struct net_device *dev) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_qdma *qdma = port->qdma; -+ int err; -+ -+ netif_tx_start_all_queues(dev); -+ err = airoha_set_gdm_ports(qdma->eth, true); -+ if (err) -+ return err; -+ -+ if (netdev_uses_dsa(dev)) -+ airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), -+ GDM_STAG_EN_MASK); -+ else -+ airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), -+ GDM_STAG_EN_MASK); -+ -+ airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, -+ GLOBAL_CFG_TX_DMA_EN_MASK | -+ GLOBAL_CFG_RX_DMA_EN_MASK); -+ -+ return 0; -+} -+ -+static int airoha_dev_stop(struct net_device *dev) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_qdma *qdma = port->qdma; -+ int i, err; -+ -+ netif_tx_disable(dev); -+ err = airoha_set_gdm_ports(qdma->eth, false); -+ if (err) -+ return err; -+ -+ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, -+ GLOBAL_CFG_TX_DMA_EN_MASK | -+ GLOBAL_CFG_RX_DMA_EN_MASK); -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -+ if (!qdma->q_tx[i].ndesc) -+ continue; -+ -+ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -+ netdev_tx_reset_subqueue(dev, i); -+ } -+ -+ return 0; -+} -+ -+static int airoha_dev_set_macaddr(struct net_device *dev, void *p) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ int err; -+ -+ err = eth_mac_addr(dev, p); -+ if (err) -+ return err; -+ -+ airoha_set_macaddr(port, dev->dev_addr); -+ -+ return 0; -+} -+ -+static int airoha_dev_init(struct net_device *dev) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ -+ airoha_set_macaddr(port, dev->dev_addr); -+ -+ return 0; -+} -+ -+static void airoha_dev_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *storage) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ unsigned int start; -+ -+ airoha_update_hw_stats(port); -+ do { -+ start = u64_stats_fetch_begin(&port->stats.syncp); -+ storage->rx_packets = port->stats.rx_ok_pkts; -+ storage->tx_packets = port->stats.tx_ok_pkts; -+ storage->rx_bytes = port->stats.rx_ok_bytes; -+ storage->tx_bytes = port->stats.tx_ok_bytes; -+ storage->multicast = port->stats.rx_multicast; -+ storage->rx_errors = port->stats.rx_errors; -+ storage->rx_dropped = port->stats.rx_drops; -+ storage->tx_dropped = port->stats.tx_drops; -+ storage->rx_crc_errors = port->stats.rx_crc_error; -+ storage->rx_over_errors = port->stats.rx_over_errors; -+ } while (u64_stats_fetch_retry(&port->stats.syncp, start)); -+} -+ -+static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ int queue, channel; -+ -+ /* For dsa device select QoS channel according to the dsa user port -+ * index, rely on port id otherwise. Select QoS queue based on the -+ * skb priority. -+ */ -+ channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; -+ channel = channel % AIROHA_NUM_QOS_CHANNELS; -+ queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ -+ queue = channel * AIROHA_NUM_QOS_QUEUES + queue; -+ -+ return queue < dev->num_tx_queues ? queue : 0; -+} -+ -+static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; -+ u32 msg0, msg1, len = skb_headlen(skb); -+ struct airoha_qdma *qdma = port->qdma; -+ struct netdev_queue *txq; -+ struct airoha_queue *q; -+ void *data = skb->data; -+ int i, qid; -+ u16 index; -+ u8 fport; -+ -+ qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); -+ msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, -+ qid / AIROHA_NUM_QOS_QUEUES) | -+ FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, -+ qid % AIROHA_NUM_QOS_QUEUES); -+ if (skb->ip_summed == CHECKSUM_PARTIAL) -+ msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | -+ FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | -+ FIELD_PREP(QDMA_ETH_TXMSG_ICO_MASK, 1); -+ -+ /* TSO: fill MSS info in tcp checksum field */ -+ if (skb_is_gso(skb)) { -+ if (skb_cow_head(skb, 0)) -+ goto error; -+ -+ if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | -+ SKB_GSO_TCPV6)) { -+ __be16 csum = cpu_to_be16(skb_shinfo(skb)->gso_size); -+ -+ tcp_hdr(skb)->check = (__force __sum16)csum; -+ msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1); -+ } -+ } -+ -+ fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; -+ msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | -+ FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); -+ -+ q = &qdma->q_tx[qid]; -+ if (WARN_ON_ONCE(!q->ndesc)) -+ goto error; -+ -+ spin_lock_bh(&q->lock); -+ -+ txq = netdev_get_tx_queue(dev, qid); -+ if (q->queued + nr_frags > q->ndesc) { -+ /* not enough space in the queue */ -+ netif_tx_stop_queue(txq); -+ spin_unlock_bh(&q->lock); -+ return NETDEV_TX_BUSY; -+ } -+ -+ index = q->head; -+ for (i = 0; i < nr_frags; i++) { -+ struct airoha_qdma_desc *desc = &q->desc[index]; -+ struct airoha_queue_entry *e = &q->entry[index]; -+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -+ dma_addr_t addr; -+ u32 val; -+ -+ addr = dma_map_single(dev->dev.parent, data, len, -+ DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(dev->dev.parent, addr))) -+ goto error_unmap; -+ -+ index = (index + 1) % q->ndesc; -+ -+ val = FIELD_PREP(QDMA_DESC_LEN_MASK, len); -+ if (i < nr_frags - 1) -+ val |= FIELD_PREP(QDMA_DESC_MORE_MASK, 1); -+ WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); -+ WRITE_ONCE(desc->addr, cpu_to_le32(addr)); -+ val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, index); -+ WRITE_ONCE(desc->data, cpu_to_le32(val)); -+ WRITE_ONCE(desc->msg0, cpu_to_le32(msg0)); -+ WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); -+ WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); -+ -+ e->skb = i ? NULL : skb; -+ e->dma_addr = addr; -+ e->dma_len = len; -+ -+ data = skb_frag_address(frag); -+ len = skb_frag_size(frag); -+ } -+ -+ q->head = index; -+ q->queued += i; -+ -+ skb_tx_timestamp(skb); -+ netdev_tx_sent_queue(txq, skb->len); -+ -+ if (netif_xmit_stopped(txq) || !netdev_xmit_more()) -+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), -+ TX_RING_CPU_IDX_MASK, -+ FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); -+ -+ if (q->ndesc - q->queued < q->free_thr) -+ netif_tx_stop_queue(txq); -+ -+ spin_unlock_bh(&q->lock); -+ -+ return NETDEV_TX_OK; -+ -+error_unmap: -+ for (i--; i >= 0; i--) { -+ index = (q->head + i) % q->ndesc; -+ dma_unmap_single(dev->dev.parent, q->entry[index].dma_addr, -+ q->entry[index].dma_len, DMA_TO_DEVICE); -+ } -+ -+ spin_unlock_bh(&q->lock); -+error: -+ dev_kfree_skb_any(skb); -+ dev->stats.tx_dropped++; -+ -+ return NETDEV_TX_OK; -+} -+ -+static void airoha_ethtool_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_eth *eth = port->qdma->eth; -+ -+ strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); -+ strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); -+} -+ -+static void airoha_ethtool_get_mac_stats(struct net_device *dev, -+ struct ethtool_eth_mac_stats *stats) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ unsigned int start; -+ -+ airoha_update_hw_stats(port); -+ do { -+ start = u64_stats_fetch_begin(&port->stats.syncp); -+ stats->MulticastFramesXmittedOK = port->stats.tx_multicast; -+ stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; -+ stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; -+ } while (u64_stats_fetch_retry(&port->stats.syncp, start)); -+} -+ -+static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = { -+ { 0, 64 }, -+ { 65, 127 }, -+ { 128, 255 }, -+ { 256, 511 }, -+ { 512, 1023 }, -+ { 1024, 1518 }, -+ { 1519, 10239 }, -+ {}, -+}; -+ -+static void -+airoha_ethtool_get_rmon_stats(struct net_device *dev, -+ struct ethtool_rmon_stats *stats, -+ const struct ethtool_rmon_hist_range **ranges) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_hw_stats *hw_stats = &port->stats; -+ unsigned int start; -+ -+ BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != -+ ARRAY_SIZE(hw_stats->tx_len) + 1); -+ BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != -+ ARRAY_SIZE(hw_stats->rx_len) + 1); -+ -+ *ranges = airoha_ethtool_rmon_ranges; -+ airoha_update_hw_stats(port); -+ do { -+ int i; -+ -+ start = u64_stats_fetch_begin(&port->stats.syncp); -+ stats->fragments = hw_stats->rx_fragment; -+ stats->jabbers = hw_stats->rx_jabber; -+ for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1; -+ i++) { -+ stats->hist[i] = hw_stats->rx_len[i]; -+ stats->hist_tx[i] = hw_stats->tx_len[i]; -+ } -+ } while (u64_stats_fetch_retry(&port->stats.syncp, start)); -+} -+ -+static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port, -+ int channel, enum tx_sched_mode mode, -+ const u16 *weights, u8 n_weights) -+{ -+ int i; -+ -+ for (i = 0; i < AIROHA_NUM_TX_RING; i++) -+ airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), -+ TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)); -+ -+ for (i = 0; i < n_weights; i++) { -+ u32 status; -+ int err; -+ -+ airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, -+ TWRR_RW_CMD_MASK | -+ FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) | -+ FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) | -+ FIELD_PREP(TWRR_VALUE_MASK, weights[i])); -+ err = read_poll_timeout(airoha_qdma_rr, status, -+ status & TWRR_RW_CMD_DONE, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, -+ true, port->qdma, -+ REG_TXWRR_WEIGHT_CFG); -+ if (err) -+ return err; -+ } -+ -+ airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), -+ CHAN_QOS_MODE_MASK(channel), -+ mode << __ffs(CHAN_QOS_MODE_MASK(channel))); -+ -+ return 0; -+} -+ -+static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port, -+ int channel) -+{ -+ static const u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -+ -+ return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w, -+ ARRAY_SIZE(w)); -+} -+ -+static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port, -+ int channel, -+ struct tc_ets_qopt_offload *opt) -+{ -+ struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; -+ enum tx_sched_mode mode = TC_SCH_SP; -+ u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -+ int i, nstrict = 0, nwrr, qidx; -+ -+ if (p->bands > AIROHA_NUM_QOS_QUEUES) -+ return -EINVAL; -+ -+ for (i = 0; i < p->bands; i++) { -+ if (!p->quanta[i]) -+ nstrict++; -+ } -+ -+ /* this configuration is not supported by the hw */ -+ if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) -+ return -EINVAL; -+ -+ /* EN7581 SoC supports fixed QoS band priority where WRR queues have -+ * lowest priorities with respect to SP ones. -+ * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn -+ */ -+ nwrr = p->bands - nstrict; -+ qidx = nstrict && nwrr ? nstrict : 0; -+ for (i = 1; i <= p->bands; i++) { -+ if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) -+ return -EINVAL; -+ -+ qidx = i == nwrr ? 0 : qidx + 1; -+ } -+ -+ for (i = 0; i < nwrr; i++) -+ w[i] = p->weights[nstrict + i]; -+ -+ if (!nstrict) -+ mode = TC_SCH_WRR8; -+ else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) -+ mode = nstrict + 1; -+ -+ return airoha_qdma_set_chan_tx_sched(port, channel, mode, w, -+ ARRAY_SIZE(w)); -+} -+ -+static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port, -+ int channel, -+ struct tc_ets_qopt_offload *opt) -+{ -+ u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, -+ REG_CNTR_VAL(channel << 1)); -+ u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, -+ REG_CNTR_VAL((channel << 1) + 1)); -+ u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + -+ (fwd_tx_packets - port->fwd_tx_packets); -+ _bstats_update(opt->stats.bstats, 0, tx_packets); -+ -+ port->cpu_tx_packets = cpu_tx_packets; -+ port->fwd_tx_packets = fwd_tx_packets; -+ -+ return 0; -+} -+ -+static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, -+ struct tc_ets_qopt_offload *opt) -+{ -+ int channel = TC_H_MAJ(opt->handle) >> 16; -+ -+ if (opt->parent == TC_H_ROOT) -+ return -EINVAL; -+ -+ switch (opt->command) { -+ case TC_ETS_REPLACE: -+ return airoha_qdma_set_tx_ets_sched(port, channel, opt); -+ case TC_ETS_DESTROY: -+ /* PRIO is default qdisc scheduler */ -+ return airoha_qdma_set_tx_prio_sched(port, channel); -+ case TC_ETS_STATS: -+ return airoha_qdma_get_tx_ets_stats(port, channel, opt); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, -+ u32 addr, enum trtcm_param_type param, -+ enum trtcm_mode_type mode, -+ u32 *val_low, u32 *val_high) -+{ -+ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); -+ u32 val, config = FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | -+ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | -+ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | -+ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); -+ -+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -+ if (read_poll_timeout(airoha_qdma_rr, val, -+ val & TRTCM_PARAM_RW_DONE_MASK, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, -+ qdma, REG_TRTCM_CFG_PARAM(addr))) -+ return -ETIMEDOUT; -+ -+ *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); -+ if (val_high) -+ *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); -+ -+ return 0; -+} -+ -+static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel, -+ u32 addr, enum trtcm_param_type param, -+ enum trtcm_mode_type mode, u32 val) -+{ -+ u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); -+ u32 config = TRTCM_PARAM_RW_MASK | -+ FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | -+ FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | -+ FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | -+ FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); -+ -+ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); -+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -+ -+ return read_poll_timeout(airoha_qdma_rr, val, -+ val & TRTCM_PARAM_RW_DONE_MASK, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, -+ qdma, REG_TRTCM_CFG_PARAM(addr)); -+} -+ -+static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel, -+ u32 addr, enum trtcm_mode_type mode, -+ bool enable, u32 enable_mask) -+{ -+ u32 val; -+ -+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -+ mode, &val, NULL)) -+ return -EINVAL; -+ -+ val = enable ? val | enable_mask : val & ~enable_mask; -+ -+ return airoha_qdma_set_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -+ mode, val); -+} -+ -+static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma, -+ int channel, u32 addr, -+ enum trtcm_mode_type mode, -+ u32 rate_val, u32 bucket_size) -+{ -+ u32 val, config, tick, unit, rate, rate_frac; -+ int err; -+ -+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -+ mode, &config, NULL)) -+ return -EINVAL; -+ -+ val = airoha_qdma_rr(qdma, addr); -+ tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); -+ if (config & TRTCM_TICK_SEL) -+ tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); -+ if (!tick) -+ return -EINVAL; -+ -+ unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; -+ if (!unit) -+ return -EINVAL; -+ -+ rate = rate_val / unit; -+ rate_frac = rate_val % unit; -+ rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; -+ rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | -+ FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); -+ -+ err = airoha_qdma_set_trtcm_param(qdma, channel, addr, -+ TRTCM_TOKEN_RATE_MODE, mode, rate); -+ if (err) -+ return err; -+ -+ val = max_t(u32, bucket_size, MIN_TOKEN_SIZE); -+ val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); -+ -+ return airoha_qdma_set_trtcm_param(qdma, channel, addr, -+ TRTCM_BUCKETSIZE_SHIFT_MODE, -+ mode, val); -+} -+ -+static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port, -+ int channel, u32 rate, -+ u32 bucket_size) -+{ -+ int i, err; -+ -+ for (i = 0; i <= TRTCM_PEAK_MODE; i++) { -+ err = airoha_qdma_set_trtcm_config(port->qdma, channel, -+ REG_EGRESS_TRTCM_CFG, i, -+ !!rate, TRTCM_METER_MODE); -+ if (err) -+ return err; -+ -+ err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, -+ REG_EGRESS_TRTCM_CFG, -+ i, rate, bucket_size); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ -+ struct net_device *dev = port->dev; -+ int num_tx_queues = dev->real_num_tx_queues; -+ int err; -+ -+ if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { -+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); -+ return -EINVAL; -+ } -+ -+ err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); -+ if (err) { -+ NL_SET_ERR_MSG_MOD(opt->extack, -+ "failed configuring htb offload"); -+ return err; -+ } -+ -+ if (opt->command == TC_HTB_NODE_MODIFY) -+ return 0; -+ -+ err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); -+ if (err) { -+ airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); -+ NL_SET_ERR_MSG_MOD(opt->extack, -+ "failed setting real_num_tx_queues"); -+ return err; -+ } -+ -+ set_bit(channel, port->qos_sq_bmap); -+ opt->qid = AIROHA_NUM_TX_RING + channel; -+ -+ return 0; -+} -+ -+static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) -+{ -+ struct net_device *dev = port->dev; -+ -+ netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); -+ airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0); -+ clear_bit(queue, port->qos_sq_bmap); -+} -+ -+static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ -+ if (!test_bit(channel, port->qos_sq_bmap)) { -+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -+ return -EINVAL; -+ } -+ -+ airoha_tc_remove_htb_queue(port, channel); -+ -+ return 0; -+} -+ -+static int airoha_tc_htb_destroy(struct airoha_gdm_port *port) -+{ -+ int q; -+ -+ for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) -+ airoha_tc_remove_htb_queue(port, q); -+ -+ return 0; -+} -+ -+static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ -+ if (!test_bit(channel, port->qos_sq_bmap)) { -+ NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -+ return -EINVAL; -+ } -+ -+ opt->qid = channel; -+ -+ return 0; -+} -+ -+static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port, -+ struct tc_htb_qopt_offload *opt) -+{ -+ switch (opt->command) { -+ case TC_HTB_CREATE: -+ break; -+ case TC_HTB_DESTROY: -+ return airoha_tc_htb_destroy(port); -+ case TC_HTB_NODE_MODIFY: -+ case TC_HTB_LEAF_ALLOC_QUEUE: -+ return airoha_tc_htb_alloc_leaf_queue(port, opt); -+ case TC_HTB_LEAF_DEL: -+ case TC_HTB_LEAF_DEL_LAST: -+ case TC_HTB_LEAF_DEL_LAST_FORCE: -+ return airoha_tc_htb_delete_leaf_queue(port, opt); -+ case TC_HTB_LEAF_QUERY_QUEUE: -+ return airoha_tc_get_htb_get_leaf_queue(port, opt); -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, -+ void *type_data) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ -+ switch (type) { -+ case TC_SETUP_QDISC_ETS: -+ return airoha_tc_setup_qdisc_ets(port, type_data); -+ case TC_SETUP_QDISC_HTB: -+ return airoha_tc_setup_qdisc_htb(port, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static const struct net_device_ops airoha_netdev_ops = { -+ .ndo_init = airoha_dev_init, -+ .ndo_open = airoha_dev_open, -+ .ndo_stop = airoha_dev_stop, -+ .ndo_select_queue = airoha_dev_select_queue, -+ .ndo_start_xmit = airoha_dev_xmit, -+ .ndo_get_stats64 = airoha_dev_get_stats64, -+ .ndo_set_mac_address = airoha_dev_set_macaddr, -+ .ndo_setup_tc = airoha_dev_tc_setup, -+}; -+ -+static const struct ethtool_ops airoha_ethtool_ops = { -+ .get_drvinfo = airoha_ethtool_get_drvinfo, -+ .get_eth_mac_stats = airoha_ethtool_get_mac_stats, -+ .get_rmon_stats = airoha_ethtool_get_rmon_stats, -+}; -+ -+static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) -+{ -+ const __be32 *id_ptr = of_get_property(np, "reg", NULL); -+ struct airoha_gdm_port *port; -+ struct airoha_qdma *qdma; -+ struct net_device *dev; -+ int err, index; -+ u32 id; -+ -+ if (!id_ptr) { -+ dev_err(eth->dev, "missing gdm port id\n"); -+ return -EINVAL; -+ } -+ -+ id = be32_to_cpup(id_ptr); -+ index = id - 1; -+ -+ if (!id || id > ARRAY_SIZE(eth->ports)) { -+ dev_err(eth->dev, "invalid gdm port id: %d\n", id); -+ return -EINVAL; -+ } -+ -+ if (eth->ports[index]) { -+ dev_err(eth->dev, "duplicate gdm port id: %d\n", id); -+ return -EINVAL; -+ } -+ -+ dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), -+ AIROHA_NUM_NETDEV_TX_RINGS, -+ AIROHA_NUM_RX_RING); -+ if (!dev) { -+ dev_err(eth->dev, "alloc_etherdev failed\n"); -+ return -ENOMEM; -+ } -+ -+ qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA]; -+ dev->netdev_ops = &airoha_netdev_ops; -+ dev->ethtool_ops = &airoha_ethtool_ops; -+ dev->max_mtu = AIROHA_MAX_MTU; -+ dev->watchdog_timeo = 5 * HZ; -+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | -+ NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | -+ NETIF_F_SG | NETIF_F_TSO | -+ NETIF_F_HW_TC; -+ dev->features |= dev->hw_features; -+ dev->dev.of_node = np; -+ dev->irq = qdma->irq; -+ SET_NETDEV_DEV(dev, eth->dev); -+ -+ /* reserve hw queues for HTB offloading */ -+ err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING); -+ if (err) -+ return err; -+ -+ err = of_get_ethdev_address(np, dev); -+ if (err) { -+ if (err == -EPROBE_DEFER) -+ return err; -+ -+ eth_hw_addr_random(dev); -+ dev_info(eth->dev, "generated random MAC address %pM\n", -+ dev->dev_addr); -+ } -+ -+ port = netdev_priv(dev); -+ u64_stats_init(&port->stats.syncp); -+ spin_lock_init(&port->stats.lock); -+ port->qdma = qdma; -+ port->dev = dev; -+ port->id = id; -+ eth->ports[index] = port; -+ -+ return register_netdev(dev); -+} -+ -+static int airoha_probe(struct platform_device *pdev) -+{ -+ struct device_node *np; -+ struct airoha_eth *eth; -+ int i, err; -+ -+ eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); -+ if (!eth) -+ return -ENOMEM; -+ -+ eth->dev = &pdev->dev; -+ -+ err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); -+ if (err) { -+ dev_err(eth->dev, "failed configuring DMA mask\n"); -+ return err; -+ } -+ -+ eth->fe_regs = devm_platform_ioremap_resource_byname(pdev, "fe"); -+ if (IS_ERR(eth->fe_regs)) -+ return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs), -+ "failed to iomap fe regs\n"); -+ -+ eth->rsts[0].id = "fe"; -+ eth->rsts[1].id = "pdma"; -+ eth->rsts[2].id = "qdma"; -+ err = devm_reset_control_bulk_get_exclusive(eth->dev, -+ ARRAY_SIZE(eth->rsts), -+ eth->rsts); -+ if (err) { -+ dev_err(eth->dev, "failed to get bulk reset lines\n"); -+ return err; -+ } -+ -+ eth->xsi_rsts[0].id = "xsi-mac"; -+ eth->xsi_rsts[1].id = "hsi0-mac"; -+ eth->xsi_rsts[2].id = "hsi1-mac"; -+ eth->xsi_rsts[3].id = "hsi-mac"; -+ eth->xsi_rsts[4].id = "xfp-mac"; -+ err = devm_reset_control_bulk_get_exclusive(eth->dev, -+ ARRAY_SIZE(eth->xsi_rsts), -+ eth->xsi_rsts); -+ if (err) { -+ dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); -+ return err; -+ } -+ -+ eth->napi_dev = alloc_netdev_dummy(0); -+ if (!eth->napi_dev) -+ return -ENOMEM; -+ -+ /* Enable threaded NAPI by default */ -+ eth->napi_dev->threaded = true; -+ strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name)); -+ platform_set_drvdata(pdev, eth); -+ -+ err = airoha_hw_init(pdev, eth); -+ if (err) -+ goto error_hw_cleanup; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -+ airoha_qdma_start_napi(ð->qdma[i]); -+ -+ for_each_child_of_node(pdev->dev.of_node, np) { -+ if (!of_device_is_compatible(np, "airoha,eth-mac")) -+ continue; -+ -+ if (!of_device_is_available(np)) -+ continue; -+ -+ err = airoha_alloc_gdm_port(eth, np); -+ if (err) { -+ of_node_put(np); -+ goto error_napi_stop; -+ } -+ } -+ -+ return 0; -+ -+error_napi_stop: -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -+ airoha_qdma_stop_napi(ð->qdma[i]); -+error_hw_cleanup: -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -+ airoha_hw_cleanup(ð->qdma[i]); -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *port = eth->ports[i]; -+ -+ if (port && port->dev->reg_state == NETREG_REGISTERED) -+ unregister_netdev(port->dev); -+ } -+ free_netdev(eth->napi_dev); -+ platform_set_drvdata(pdev, NULL); -+ -+ return err; -+} -+ -+static void airoha_remove(struct platform_device *pdev) -+{ -+ struct airoha_eth *eth = platform_get_drvdata(pdev); -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { -+ airoha_qdma_stop_napi(ð->qdma[i]); -+ airoha_hw_cleanup(ð->qdma[i]); -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *port = eth->ports[i]; -+ -+ if (!port) -+ continue; -+ -+ unregister_netdev(port->dev); -+ } -+ free_netdev(eth->napi_dev); -+ -+ platform_set_drvdata(pdev, NULL); -+} -+ -+static const struct of_device_id of_airoha_match[] = { -+ { .compatible = "airoha,en7581-eth" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, of_airoha_match); -+ -+static struct platform_driver airoha_driver = { -+ .probe = airoha_probe, -+ .remove_new = airoha_remove, -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = of_airoha_match, -+ }, -+}; -+module_platform_driver(airoha_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Lorenzo Bianconi "); -+MODULE_DESCRIPTION("Ethernet driver for Airoha SoC"); ---- a/drivers/net/ethernet/mediatek/airoha_eth.c -+++ /dev/null -@@ -1,3378 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* -- * Copyright (c) 2024 AIROHA Inc -- * Author: Lorenzo Bianconi -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define AIROHA_MAX_NUM_GDM_PORTS 1 --#define AIROHA_MAX_NUM_QDMA 2 --#define AIROHA_MAX_NUM_RSTS 3 --#define AIROHA_MAX_NUM_XSI_RSTS 5 --#define AIROHA_MAX_MTU 2000 --#define AIROHA_MAX_PACKET_SIZE 2048 --#define AIROHA_NUM_QOS_CHANNELS 4 --#define AIROHA_NUM_QOS_QUEUES 8 --#define AIROHA_NUM_TX_RING 32 --#define AIROHA_NUM_RX_RING 32 --#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ -- AIROHA_NUM_QOS_CHANNELS) --#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 --#define AIROHA_FE_MC_MAX_VLAN_PORT 16 --#define AIROHA_NUM_TX_IRQ 2 --#define HW_DSCP_NUM 2048 --#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) --#define TX_DSCP_NUM 1024 --#define RX_DSCP_NUM(_n) \ -- ((_n) == 2 ? 128 : \ -- (_n) == 11 ? 128 : \ -- (_n) == 15 ? 128 : \ -- (_n) == 0 ? 1024 : 16) -- --#define PSE_RSV_PAGES 128 --#define PSE_QUEUE_RSV_PAGES 64 -- --#define QDMA_METER_IDX(_n) ((_n) & 0xff) --#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) -- --/* FE */ --#define PSE_BASE 0x0100 --#define CSR_IFC_BASE 0x0200 --#define CDM1_BASE 0x0400 --#define GDM1_BASE 0x0500 --#define PPE1_BASE 0x0c00 -- --#define CDM2_BASE 0x1400 --#define GDM2_BASE 0x1500 -- --#define GDM3_BASE 0x1100 --#define GDM4_BASE 0x2500 -- --#define GDM_BASE(_n) \ -- ((_n) == 4 ? GDM4_BASE : \ -- (_n) == 3 ? GDM3_BASE : \ -- (_n) == 2 ? GDM2_BASE : GDM1_BASE) -- --#define REG_FE_DMA_GLO_CFG 0x0000 --#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) --#define FE_DMA_GLO_PG_SZ_MASK BIT(3) -- --#define REG_FE_RST_GLO_CFG 0x0004 --#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) --#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) --#define FE_RST_CORE_MASK BIT(0) -- --#define REG_FE_WAN_MAC_H 0x0030 --#define REG_FE_LAN_MAC_H 0x0040 -- --#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) --#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) -- --#define REG_FE_CDM1_OQ_MAP0 0x0050 --#define REG_FE_CDM1_OQ_MAP1 0x0054 --#define REG_FE_CDM1_OQ_MAP2 0x0058 --#define REG_FE_CDM1_OQ_MAP3 0x005c -- --#define REG_FE_PCE_CFG 0x0070 --#define PCE_DPI_EN_MASK BIT(2) --#define PCE_KA_EN_MASK BIT(1) --#define PCE_MC_EN_MASK BIT(0) -- --#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 --#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) --#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) --#define PSE_CFG_WR_EN_MASK BIT(8) --#define PSE_CFG_OQRSV_SEL_MASK BIT(0) -- --#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 --#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) -- --#define PSE_FQ_CFG 0x008c --#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) -- --#define REG_FE_PSE_BUF_SET 0x0090 --#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) --#define PSE_ALLRSV_MASK GENMASK(14, 0) -- --#define REG_PSE_SHARE_USED_THD 0x0094 --#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) --#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) -- --#define REG_GDM_MISC_CFG 0x0148 --#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) --#define GDM2_CHN_VLD_MODE_MASK BIT(5) -- --#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE --#define FE_IFC_EN_MASK BIT(0) -- --#define REG_FE_VIP_PORT_EN 0x01f0 --#define REG_FE_IFC_PORT_EN 0x01f4 -- --#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) --#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) -- --#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) --#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) --#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) -- --#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) --#define PATN_FCPU_EN_MASK BIT(7) --#define PATN_SWP_EN_MASK BIT(6) --#define PATN_DP_EN_MASK BIT(5) --#define PATN_SP_EN_MASK BIT(4) --#define PATN_TYPE_MASK GENMASK(3, 1) --#define PATN_EN_MASK BIT(0) -- --#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) --#define PATN_DP_MASK GENMASK(31, 16) --#define PATN_SP_MASK GENMASK(15, 0) -- --#define REG_CDM1_VLAN_CTRL CDM1_BASE --#define CDM1_VLAN_MASK GENMASK(31, 16) -- --#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) --#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) -- --#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) --#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ -- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -- --#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) --#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) --#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) -- --#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) --#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ -- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -- --#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) --#define GDM_DROP_CRC_ERR BIT(23) --#define GDM_IP4_CKSUM BIT(22) --#define GDM_TCP_CKSUM BIT(21) --#define GDM_UDP_CKSUM BIT(20) --#define GDM_UCFQ_MASK GENMASK(15, 12) --#define GDM_BCFQ_MASK GENMASK(11, 8) --#define GDM_MCFQ_MASK GENMASK(7, 4) --#define GDM_OCFQ_MASK GENMASK(3, 0) -- --#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) --#define GDM_INGRESS_FC_EN_MASK BIT(1) --#define GDM_STAG_EN_MASK BIT(0) -- --#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) --#define GDM_SHORT_LEN_MASK GENMASK(13, 0) --#define GDM_LONG_LEN_MASK GENMASK(29, 16) -- --#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) --#define FE_CPORT_PAD BIT(26) --#define FE_CPORT_PORT_XFC_MASK BIT(25) --#define FE_CPORT_QUEUE_XFC_MASK BIT(24) -- --#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) --#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) --#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) -- --#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) --#define FE_STRICT_RFC2819_MODE_MASK BIT(31) --#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) --#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) --#define FE_TX_MIB_ID_MASK GENMASK(15, 8) --#define FE_RX_MIB_ID_MASK GENMASK(7, 0) -- --#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) --#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) --#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) --#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) --#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) --#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) --#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) --#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) --#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) --#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) --#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) --#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) --#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) --#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) --#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) -- --#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) --#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) --#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) --#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) --#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) --#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) --#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) --#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) --#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) --#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) --#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) --#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) --#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) --#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) --#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) --#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) --#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) --#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) --#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) --#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) --#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) --#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) -- --#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) --#define PPE1_SRAM_TABLE_EN_MASK BIT(0) --#define PPE1_SRAM_HASH1_EN_MASK BIT(8) --#define PPE1_DRAM_TABLE_EN_MASK BIT(16) --#define PPE1_DRAM_HASH1_EN_MASK BIT(24) -- --#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) --#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) --#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) --#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) -- --#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) --#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) --#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) --#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) --#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) --#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) --#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) --#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) --#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) --#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) --#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) --#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) --#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) --#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) --#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) --#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) -- --#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) --#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) --#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) -- --#define REG_GDM3_FWD_CFG GDM3_BASE --#define GDM3_PAD_EN_MASK BIT(28) -- --#define REG_GDM4_FWD_CFG GDM4_BASE --#define GDM4_PAD_EN_MASK BIT(28) --#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) -- --#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) --#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) --#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) --#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) -- --#define REG_IP_FRAG_FP 0x2010 --#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) --#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) --#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) --#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) -- --#define REG_MC_VLAN_EN 0x2100 --#define MC_VLAN_EN_MASK BIT(0) -- --#define REG_MC_VLAN_CFG 0x2104 --#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) --#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) --#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) --#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) --#define MC_VLAN_CFG_RW_MASK BIT(0) -- --#define REG_MC_VLAN_DATA 0x2108 -- --#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 -- --/* QDMA */ --#define REG_QDMA_GLOBAL_CFG 0x0004 --#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) --#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) --#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) --#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) --#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) --#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) --#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) --#define GLOBAL_CFG_RESET_MASK BIT(23) --#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) --#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) --#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) --#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) --#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) --#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) --#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) --#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) --#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) --#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) --#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) --#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) --#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) --#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) --#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) -- --#define REG_FWD_DSCP_BASE 0x0010 --#define REG_FWD_BUF_BASE 0x0014 -- --#define REG_HW_FWD_DSCP_CFG 0x0018 --#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) --#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) --#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) -- --#define REG_INT_STATUS(_n) \ -- (((_n) == 4) ? 0x0730 : \ -- ((_n) == 3) ? 0x0724 : \ -- ((_n) == 2) ? 0x0720 : \ -- ((_n) == 1) ? 0x0024 : 0x0020) -- --#define REG_INT_ENABLE(_n) \ -- (((_n) == 4) ? 0x0750 : \ -- ((_n) == 3) ? 0x0744 : \ -- ((_n) == 2) ? 0x0740 : \ -- ((_n) == 1) ? 0x002c : 0x0028) -- --/* QDMA_CSR_INT_ENABLE1 */ --#define RX15_COHERENT_INT_MASK BIT(31) --#define RX14_COHERENT_INT_MASK BIT(30) --#define RX13_COHERENT_INT_MASK BIT(29) --#define RX12_COHERENT_INT_MASK BIT(28) --#define RX11_COHERENT_INT_MASK BIT(27) --#define RX10_COHERENT_INT_MASK BIT(26) --#define RX9_COHERENT_INT_MASK BIT(25) --#define RX8_COHERENT_INT_MASK BIT(24) --#define RX7_COHERENT_INT_MASK BIT(23) --#define RX6_COHERENT_INT_MASK BIT(22) --#define RX5_COHERENT_INT_MASK BIT(21) --#define RX4_COHERENT_INT_MASK BIT(20) --#define RX3_COHERENT_INT_MASK BIT(19) --#define RX2_COHERENT_INT_MASK BIT(18) --#define RX1_COHERENT_INT_MASK BIT(17) --#define RX0_COHERENT_INT_MASK BIT(16) --#define TX7_COHERENT_INT_MASK BIT(15) --#define TX6_COHERENT_INT_MASK BIT(14) --#define TX5_COHERENT_INT_MASK BIT(13) --#define TX4_COHERENT_INT_MASK BIT(12) --#define TX3_COHERENT_INT_MASK BIT(11) --#define TX2_COHERENT_INT_MASK BIT(10) --#define TX1_COHERENT_INT_MASK BIT(9) --#define TX0_COHERENT_INT_MASK BIT(8) --#define CNT_OVER_FLOW_INT_MASK BIT(7) --#define IRQ1_FULL_INT_MASK BIT(5) --#define IRQ1_INT_MASK BIT(4) --#define HWFWD_DSCP_LOW_INT_MASK BIT(3) --#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) --#define IRQ0_FULL_INT_MASK BIT(1) --#define IRQ0_INT_MASK BIT(0) -- --#define TX_DONE_INT_MASK(_n) \ -- ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ -- : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -- --#define INT_TX_MASK \ -- (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ -- IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -- --#define INT_IDX0_MASK \ -- (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ -- TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ -- TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ -- TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ -- RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ -- RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ -- RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ -- RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ -- RX15_COHERENT_INT_MASK | INT_TX_MASK) -- --/* QDMA_CSR_INT_ENABLE2 */ --#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) --#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) --#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) --#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) --#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) --#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) --#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) --#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) --#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) --#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) --#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) --#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) --#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) --#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) --#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) --#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) --#define RX15_DONE_INT_MASK BIT(15) --#define RX14_DONE_INT_MASK BIT(14) --#define RX13_DONE_INT_MASK BIT(13) --#define RX12_DONE_INT_MASK BIT(12) --#define RX11_DONE_INT_MASK BIT(11) --#define RX10_DONE_INT_MASK BIT(10) --#define RX9_DONE_INT_MASK BIT(9) --#define RX8_DONE_INT_MASK BIT(8) --#define RX7_DONE_INT_MASK BIT(7) --#define RX6_DONE_INT_MASK BIT(6) --#define RX5_DONE_INT_MASK BIT(5) --#define RX4_DONE_INT_MASK BIT(4) --#define RX3_DONE_INT_MASK BIT(3) --#define RX2_DONE_INT_MASK BIT(2) --#define RX1_DONE_INT_MASK BIT(1) --#define RX0_DONE_INT_MASK BIT(0) -- --#define RX_DONE_INT_MASK \ -- (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ -- RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ -- RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ -- RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ -- RX15_DONE_INT_MASK) --#define INT_IDX1_MASK \ -- (RX_DONE_INT_MASK | \ -- RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ -- RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ -- RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ -- RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ -- RX15_NO_CPU_DSCP_INT_MASK) -- --/* QDMA_CSR_INT_ENABLE5 */ --#define TX31_COHERENT_INT_MASK BIT(31) --#define TX30_COHERENT_INT_MASK BIT(30) --#define TX29_COHERENT_INT_MASK BIT(29) --#define TX28_COHERENT_INT_MASK BIT(28) --#define TX27_COHERENT_INT_MASK BIT(27) --#define TX26_COHERENT_INT_MASK BIT(26) --#define TX25_COHERENT_INT_MASK BIT(25) --#define TX24_COHERENT_INT_MASK BIT(24) --#define TX23_COHERENT_INT_MASK BIT(23) --#define TX22_COHERENT_INT_MASK BIT(22) --#define TX21_COHERENT_INT_MASK BIT(21) --#define TX20_COHERENT_INT_MASK BIT(20) --#define TX19_COHERENT_INT_MASK BIT(19) --#define TX18_COHERENT_INT_MASK BIT(18) --#define TX17_COHERENT_INT_MASK BIT(17) --#define TX16_COHERENT_INT_MASK BIT(16) --#define TX15_COHERENT_INT_MASK BIT(15) --#define TX14_COHERENT_INT_MASK BIT(14) --#define TX13_COHERENT_INT_MASK BIT(13) --#define TX12_COHERENT_INT_MASK BIT(12) --#define TX11_COHERENT_INT_MASK BIT(11) --#define TX10_COHERENT_INT_MASK BIT(10) --#define TX9_COHERENT_INT_MASK BIT(9) --#define TX8_COHERENT_INT_MASK BIT(8) -- --#define INT_IDX4_MASK \ -- (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ -- TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ -- TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ -- TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ -- TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ -- TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ -- TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ -- TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ -- TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ -- TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ -- TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ -- TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) -- --#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) -- --#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) --#define TX_IRQ_THR_MASK GENMASK(27, 16) --#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) -- --#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) --#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) -- --#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) --#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) --#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) -- --#define REG_TX_RING_BASE(_n) \ -- (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) -- --#define REG_TX_RING_BLOCKING(_n) \ -- (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) -- --#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) --#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) --#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) --#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) --#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) -- --#define REG_TX_CPU_IDX(_n) \ -- (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) -- --#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) -- --#define REG_TX_DMA_IDX(_n) \ -- (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) -- --#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) -- --#define IRQ_RING_IDX_MASK GENMASK(20, 16) --#define IRQ_DESC_IDX_MASK GENMASK(15, 0) -- --#define REG_RX_RING_BASE(_n) \ -- (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) -- --#define REG_RX_RING_SIZE(_n) \ -- (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) -- --#define RX_RING_THR_MASK GENMASK(31, 16) --#define RX_RING_SIZE_MASK GENMASK(15, 0) -- --#define REG_RX_CPU_IDX(_n) \ -- (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) -- --#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) -- --#define REG_RX_DMA_IDX(_n) \ -- (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) -- --#define REG_RX_DELAY_INT_IDX(_n) \ -- (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) -- --#define RX_DELAY_INT_MASK GENMASK(15, 0) -- --#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) -- --#define REG_INGRESS_TRTCM_CFG 0x0070 --#define INGRESS_TRTCM_EN_MASK BIT(31) --#define INGRESS_TRTCM_MODE_MASK BIT(30) --#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) -- --#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) --#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) -- --#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) --#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) -- --#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) --#define CNTR_EN_MASK BIT(31) --#define CNTR_ALL_CHAN_EN_MASK BIT(30) --#define CNTR_ALL_QUEUE_EN_MASK BIT(29) --#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) --#define CNTR_SRC_MASK GENMASK(27, 24) --#define CNTR_DSCP_RING_MASK GENMASK(20, 16) --#define CNTR_CHAN_MASK GENMASK(7, 3) --#define CNTR_QUEUE_MASK GENMASK(2, 0) -- --#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) -- --#define REG_LMGR_INIT_CFG 0x1000 --#define LMGR_INIT_START BIT(31) --#define LMGR_SRAM_MODE_MASK BIT(30) --#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) --#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) -- --#define REG_FWD_DSCP_LOW_THR 0x1004 --#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) -- --#define REG_EGRESS_RATE_METER_CFG 0x100c --#define EGRESS_RATE_METER_EN_MASK BIT(31) --#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) --#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) --#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) -- --#define REG_EGRESS_TRTCM_CFG 0x1010 --#define EGRESS_TRTCM_EN_MASK BIT(31) --#define EGRESS_TRTCM_MODE_MASK BIT(30) --#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) -- --#define TRTCM_PARAM_RW_MASK BIT(31) --#define TRTCM_PARAM_RW_DONE_MASK BIT(30) --#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) --#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) --#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) --#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) -- --#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) --#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) --#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) -- --#define REG_TXWRR_MODE_CFG 0x1020 --#define TWRR_WEIGHT_SCALE_MASK BIT(31) --#define TWRR_WEIGHT_BASE_MASK BIT(3) -- --#define REG_TXWRR_WEIGHT_CFG 0x1024 --#define TWRR_RW_CMD_MASK BIT(31) --#define TWRR_RW_CMD_DONE BIT(30) --#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) --#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) --#define TWRR_VALUE_MASK GENMASK(15, 0) -- --#define REG_PSE_BUF_USAGE_CFG 0x1028 --#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) -- --#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) --#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) -- --#define REG_GLB_TRTCM_CFG 0x1080 --#define GLB_TRTCM_EN_MASK BIT(31) --#define GLB_TRTCM_MODE_MASK BIT(30) --#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define GLB_FAST_TICK_MASK GENMASK(15, 0) -- --#define REG_TXQ_CNGST_CFG 0x10a0 --#define TXQ_CNGST_DROP_EN BIT(31) --#define TXQ_CNGST_DEI_DROP_EN BIT(30) -- --#define REG_SLA_TRTCM_CFG 0x1150 --#define SLA_TRTCM_EN_MASK BIT(31) --#define SLA_TRTCM_MODE_MASK BIT(30) --#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define SLA_FAST_TICK_MASK GENMASK(15, 0) -- --/* CTRL */ --#define QDMA_DESC_DONE_MASK BIT(31) --#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ --#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ --#define QDMA_DESC_DEI_MASK BIT(25) --#define QDMA_DESC_NO_DROP_MASK BIT(24) --#define QDMA_DESC_LEN_MASK GENMASK(15, 0) --/* DATA */ --#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) --/* TX MSG0 */ --#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) --#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) --#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) --#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) --#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) --#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) --#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) --#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) --#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) --#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) --/* TX MSG1 */ --#define QDMA_ETH_TXMSG_NO_DROP BIT(31) --#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ --#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) --#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) --#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) --#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) --#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) --#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ --#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ -- --/* RX MSG1 */ --#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) --#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) --#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) --#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) --#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) --#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) --#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) --#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) --#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) -- --struct airoha_qdma_desc { -- __le32 rsv; -- __le32 ctrl; -- __le32 addr; -- __le32 data; -- __le32 msg0; -- __le32 msg1; -- __le32 msg2; -- __le32 msg3; --}; -- --/* CTRL0 */ --#define QDMA_FWD_DESC_CTX_MASK BIT(31) --#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) --#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) --#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) --/* CTRL1 */ --#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) --/* CTRL2 */ --#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) -- --struct airoha_qdma_fwd_desc { -- __le32 addr; -- __le32 ctrl0; -- __le32 ctrl1; -- __le32 ctrl2; -- __le32 msg0; -- __le32 msg1; -- __le32 rsv0; -- __le32 rsv1; --}; -- --enum { -- QDMA_INT_REG_IDX0, -- QDMA_INT_REG_IDX1, -- QDMA_INT_REG_IDX2, -- QDMA_INT_REG_IDX3, -- QDMA_INT_REG_IDX4, -- QDMA_INT_REG_MAX --}; -- --enum { -- XSI_PCIE0_PORT, -- XSI_PCIE1_PORT, -- XSI_USB_PORT, -- XSI_AE_PORT, -- XSI_ETH_PORT, --}; -- --enum { -- XSI_PCIE0_VIP_PORT_MASK = BIT(22), -- XSI_PCIE1_VIP_PORT_MASK = BIT(23), -- XSI_USB_VIP_PORT_MASK = BIT(25), -- XSI_ETH_VIP_PORT_MASK = BIT(24), --}; -- --enum { -- DEV_STATE_INITIALIZED, --}; -- --enum { -- CDM_CRSN_QSEL_Q1 = 1, -- CDM_CRSN_QSEL_Q5 = 5, -- CDM_CRSN_QSEL_Q6 = 6, -- CDM_CRSN_QSEL_Q15 = 15, --}; -- --enum { -- CRSN_08 = 0x8, -- CRSN_21 = 0x15, /* KA */ -- CRSN_22 = 0x16, /* hit bind and force route to CPU */ -- CRSN_24 = 0x18, -- CRSN_25 = 0x19, --}; -- --enum { -- FE_PSE_PORT_CDM1, -- FE_PSE_PORT_GDM1, -- FE_PSE_PORT_GDM2, -- FE_PSE_PORT_GDM3, -- FE_PSE_PORT_PPE1, -- FE_PSE_PORT_CDM2, -- FE_PSE_PORT_CDM3, -- FE_PSE_PORT_CDM4, -- FE_PSE_PORT_PPE2, -- FE_PSE_PORT_GDM4, -- FE_PSE_PORT_CDM5, -- FE_PSE_PORT_DROP = 0xf, --}; -- --enum tx_sched_mode { -- TC_SCH_WRR8, -- TC_SCH_SP, -- TC_SCH_WRR7, -- TC_SCH_WRR6, -- TC_SCH_WRR5, -- TC_SCH_WRR4, -- TC_SCH_WRR3, -- TC_SCH_WRR2, --}; -- --enum trtcm_param_type { -- TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ -- TRTCM_TOKEN_RATE_MODE, -- TRTCM_BUCKETSIZE_SHIFT_MODE, -- TRTCM_BUCKET_COUNTER_MODE, --}; -- --enum trtcm_mode_type { -- TRTCM_COMMIT_MODE, -- TRTCM_PEAK_MODE, --}; -- --enum trtcm_param { -- TRTCM_TICK_SEL = BIT(0), -- TRTCM_PKT_MODE = BIT(1), -- TRTCM_METER_MODE = BIT(2), --}; -- --#define MIN_TOKEN_SIZE 4096 --#define MAX_TOKEN_SIZE_OFFSET 17 --#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) --#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) -- --struct airoha_queue_entry { -- union { -- void *buf; -- struct sk_buff *skb; -- }; -- dma_addr_t dma_addr; -- u16 dma_len; --}; -- --struct airoha_queue { -- struct airoha_qdma *qdma; -- -- /* protect concurrent queue accesses */ -- spinlock_t lock; -- struct airoha_queue_entry *entry; -- struct airoha_qdma_desc *desc; -- u16 head; -- u16 tail; -- -- int queued; -- int ndesc; -- int free_thr; -- int buf_size; -- -- struct napi_struct napi; -- struct page_pool *page_pool; --}; -- --struct airoha_tx_irq_queue { -- struct airoha_qdma *qdma; -- -- struct napi_struct napi; -- -- int size; -- u32 *q; --}; -- --struct airoha_hw_stats { -- /* protect concurrent hw_stats accesses */ -- spinlock_t lock; -- struct u64_stats_sync syncp; -- -- /* get_stats64 */ -- u64 rx_ok_pkts; -- u64 tx_ok_pkts; -- u64 rx_ok_bytes; -- u64 tx_ok_bytes; -- u64 rx_multicast; -- u64 rx_errors; -- u64 rx_drops; -- u64 tx_drops; -- u64 rx_crc_error; -- u64 rx_over_errors; -- /* ethtool stats */ -- u64 tx_broadcast; -- u64 tx_multicast; -- u64 tx_len[7]; -- u64 rx_broadcast; -- u64 rx_fragment; -- u64 rx_jabber; -- u64 rx_len[7]; --}; -- --struct airoha_qdma { -- struct airoha_eth *eth; -- void __iomem *regs; -- -- /* protect concurrent irqmask accesses */ -- spinlock_t irq_lock; -- u32 irqmask[QDMA_INT_REG_MAX]; -- int irq; -- -- struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; -- -- struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; -- struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; -- -- /* descriptor and packet buffers for qdma hw forward */ -- struct { -- void *desc; -- void *q; -- } hfwd; --}; -- --struct airoha_gdm_port { -- struct airoha_qdma *qdma; -- struct net_device *dev; -- int id; -- -- struct airoha_hw_stats stats; -- -- DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); -- -- /* qos stats counters */ -- u64 cpu_tx_packets; -- u64 fwd_tx_packets; --}; -- --struct airoha_eth { -- struct device *dev; -- -- unsigned long state; -- void __iomem *fe_regs; -- -- struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; -- struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; -- -- struct net_device *napi_dev; -- -- struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; -- struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; --}; -- --static u32 airoha_rr(void __iomem *base, u32 offset) --{ -- return readl(base + offset); --} -- --static void airoha_wr(void __iomem *base, u32 offset, u32 val) --{ -- writel(val, base + offset); --} -- --static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) --{ -- val |= (airoha_rr(base, offset) & ~mask); -- airoha_wr(base, offset, val); -- -- return val; --} -- --#define airoha_fe_rr(eth, offset) \ -- airoha_rr((eth)->fe_regs, (offset)) --#define airoha_fe_wr(eth, offset, val) \ -- airoha_wr((eth)->fe_regs, (offset), (val)) --#define airoha_fe_rmw(eth, offset, mask, val) \ -- airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) --#define airoha_fe_set(eth, offset, val) \ -- airoha_rmw((eth)->fe_regs, (offset), 0, (val)) --#define airoha_fe_clear(eth, offset, val) \ -- airoha_rmw((eth)->fe_regs, (offset), (val), 0) -- --#define airoha_qdma_rr(qdma, offset) \ -- airoha_rr((qdma)->regs, (offset)) --#define airoha_qdma_wr(qdma, offset, val) \ -- airoha_wr((qdma)->regs, (offset), (val)) --#define airoha_qdma_rmw(qdma, offset, mask, val) \ -- airoha_rmw((qdma)->regs, (offset), (mask), (val)) --#define airoha_qdma_set(qdma, offset, val) \ -- airoha_rmw((qdma)->regs, (offset), 0, (val)) --#define airoha_qdma_clear(qdma, offset, val) \ -- airoha_rmw((qdma)->regs, (offset), (val), 0) -- --static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, -- u32 clear, u32 set) --{ -- unsigned long flags; -- -- if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask))) -- return; -- -- spin_lock_irqsave(&qdma->irq_lock, flags); -- -- qdma->irqmask[index] &= ~clear; -- qdma->irqmask[index] |= set; -- airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]); -- /* Read irq_enable register in order to guarantee the update above -- * completes in the spinlock critical section. -- */ -- airoha_qdma_rr(qdma, REG_INT_ENABLE(index)); -- -- spin_unlock_irqrestore(&qdma->irq_lock, flags); --} -- --static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index, -- u32 mask) --{ -- airoha_qdma_set_irqmask(qdma, index, 0, mask); --} -- --static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index, -- u32 mask) --{ -- airoha_qdma_set_irqmask(qdma, index, mask, 0); --} -- --static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) --{ -- /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. -- * GDM{2,3,4} can be used as wan port connected to an external -- * phy module. -- */ -- return port->id == 1; --} -- --static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) --{ -- struct airoha_eth *eth = port->qdma->eth; -- u32 val, reg; -- -- reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H -- : REG_FE_WAN_MAC_H; -- val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; -- airoha_fe_wr(eth, reg, val); -- -- val = (addr[3] << 16) | (addr[4] << 8) | addr[5]; -- airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); -- airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); --} -- --static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, -- u32 val) --{ -- airoha_fe_rmw(eth, addr, GDM_OCFQ_MASK, -- FIELD_PREP(GDM_OCFQ_MASK, val)); -- airoha_fe_rmw(eth, addr, GDM_MCFQ_MASK, -- FIELD_PREP(GDM_MCFQ_MASK, val)); -- airoha_fe_rmw(eth, addr, GDM_BCFQ_MASK, -- FIELD_PREP(GDM_BCFQ_MASK, val)); -- airoha_fe_rmw(eth, addr, GDM_UCFQ_MASK, -- FIELD_PREP(GDM_UCFQ_MASK, val)); --} -- --static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) --{ -- u32 val = enable ? FE_PSE_PORT_PPE1 : FE_PSE_PORT_DROP; -- u32 vip_port, cfg_addr; -- -- switch (port) { -- case XSI_PCIE0_PORT: -- vip_port = XSI_PCIE0_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(3); -- break; -- case XSI_PCIE1_PORT: -- vip_port = XSI_PCIE1_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(3); -- break; -- case XSI_USB_PORT: -- vip_port = XSI_USB_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(4); -- break; -- case XSI_ETH_PORT: -- vip_port = XSI_ETH_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(4); -- break; -- default: -- return -EINVAL; -- } -- -- if (enable) { -- airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); -- airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); -- } else { -- airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port); -- airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); -- } -- -- airoha_set_gdm_port_fwd_cfg(eth, cfg_addr, val); -- -- return 0; --} -- --static int airoha_set_gdm_ports(struct airoha_eth *eth, bool enable) --{ -- const int port_list[] = { -- XSI_PCIE0_PORT, -- XSI_PCIE1_PORT, -- XSI_USB_PORT, -- XSI_ETH_PORT -- }; -- int i, err; -- -- for (i = 0; i < ARRAY_SIZE(port_list); i++) { -- err = airoha_set_gdm_port(eth, port_list[i], enable); -- if (err) -- goto error; -- } -- -- return 0; -- --error: -- for (i--; i >= 0; i--) -- airoha_set_gdm_port(eth, port_list[i], false); -- -- return err; --} -- --static void airoha_fe_maccr_init(struct airoha_eth *eth) --{ -- int p; -- -- for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) { -- airoha_fe_set(eth, REG_GDM_FWD_CFG(p), -- GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | -- GDM_DROP_CRC_ERR); -- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(p), -- FE_PSE_PORT_CDM1); -- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), -- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -- FIELD_PREP(GDM_LONG_LEN_MASK, 4004)); -- } -- -- airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, -- FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); -- -- airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); --} -- --static void airoha_fe_vip_setup(struct airoha_eth *eth) --{ -- airoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC); -- airoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK); -- -- airoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP); -- airoha_fe_wr(eth, REG_FE_VIP_EN(4), -- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -- PATN_EN_MASK); -- -- airoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP); -- airoha_fe_wr(eth, REG_FE_VIP_EN(6), -- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -- PATN_EN_MASK); -- -- airoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP); -- airoha_fe_wr(eth, REG_FE_VIP_EN(7), -- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -- PATN_EN_MASK); -- -- /* BOOTP (0x43) */ -- airoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43); -- airoha_fe_wr(eth, REG_FE_VIP_EN(8), -- PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | -- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -- -- /* BOOTP (0x44) */ -- airoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44); -- airoha_fe_wr(eth, REG_FE_VIP_EN(9), -- PATN_FCPU_EN_MASK | PATN_SP_EN_MASK | -- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -- -- /* ISAKMP */ -- airoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4); -- airoha_fe_wr(eth, REG_FE_VIP_EN(10), -- PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | -- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -- -- airoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP); -- airoha_fe_wr(eth, REG_FE_VIP_EN(11), -- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -- PATN_EN_MASK); -- -- /* DHCPv6 */ -- airoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223); -- airoha_fe_wr(eth, REG_FE_VIP_EN(12), -- PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK | -- FIELD_PREP(PATN_TYPE_MASK, 4) | PATN_EN_MASK); -- -- airoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP); -- airoha_fe_wr(eth, REG_FE_VIP_EN(19), -- PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) | -- PATN_EN_MASK); -- -- /* ETH->ETH_P_1905 (0x893a) */ -- airoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a); -- airoha_fe_wr(eth, REG_FE_VIP_EN(20), -- PATN_FCPU_EN_MASK | PATN_EN_MASK); -- -- airoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP); -- airoha_fe_wr(eth, REG_FE_VIP_EN(21), -- PATN_FCPU_EN_MASK | PATN_EN_MASK); --} -- --static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth, -- u32 port, u32 queue) --{ -- u32 val; -- -- airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, -- PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK, -- FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | -- FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue)); -- val = airoha_fe_rr(eth, REG_FE_PSE_QUEUE_CFG_VAL); -- -- return FIELD_GET(PSE_CFG_OQ_RSV_MASK, val); --} -- --static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth, -- u32 port, u32 queue, u32 val) --{ -- airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK, -- FIELD_PREP(PSE_CFG_OQ_RSV_MASK, val)); -- airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, -- PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK | -- PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK, -- FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | -- FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue) | -- PSE_CFG_WR_EN_MASK | PSE_CFG_OQRSV_SEL_MASK); --} -- --static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth) --{ -- u32 val = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET); -- -- return FIELD_GET(PSE_ALLRSV_MASK, val); --} -- --static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth, -- u32 port, u32 queue, u32 val) --{ -- u32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue); -- u32 tmp, all_rsv, fq_limit; -- -- airoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val); -- -- /* modify all rsv */ -- all_rsv = airoha_fe_get_pse_all_rsv(eth); -- all_rsv += (val - orig_val); -- airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK, -- FIELD_PREP(PSE_ALLRSV_MASK, all_rsv)); -- -- /* modify hthd */ -- tmp = airoha_fe_rr(eth, PSE_FQ_CFG); -- fq_limit = FIELD_GET(PSE_FQ_LIMIT_MASK, tmp); -- tmp = fq_limit - all_rsv - 0x20; -- airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, -- PSE_SHARE_USED_HTHD_MASK, -- FIELD_PREP(PSE_SHARE_USED_HTHD_MASK, tmp)); -- -- tmp = fq_limit - all_rsv - 0x100; -- airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, -- PSE_SHARE_USED_MTHD_MASK, -- FIELD_PREP(PSE_SHARE_USED_MTHD_MASK, tmp)); -- tmp = (3 * tmp) >> 2; -- airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, -- PSE_SHARE_USED_LTHD_MASK, -- FIELD_PREP(PSE_SHARE_USED_LTHD_MASK, tmp)); -- -- return 0; --} -- --static void airoha_fe_pse_ports_init(struct airoha_eth *eth) --{ -- const u32 pse_port_num_queues[] = { -- [FE_PSE_PORT_CDM1] = 6, -- [FE_PSE_PORT_GDM1] = 6, -- [FE_PSE_PORT_GDM2] = 32, -- [FE_PSE_PORT_GDM3] = 6, -- [FE_PSE_PORT_PPE1] = 4, -- [FE_PSE_PORT_CDM2] = 6, -- [FE_PSE_PORT_CDM3] = 8, -- [FE_PSE_PORT_CDM4] = 10, -- [FE_PSE_PORT_PPE2] = 4, -- [FE_PSE_PORT_GDM4] = 2, -- [FE_PSE_PORT_CDM5] = 2, -- }; -- u32 all_rsv; -- int q; -- -- all_rsv = airoha_fe_get_pse_all_rsv(eth); -- /* hw misses PPE2 oq rsv */ -- all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; -- airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); -- -- /* CMD1 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q, -- PSE_QUEUE_RSV_PAGES); -- /* GMD1 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM1]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q, -- PSE_QUEUE_RSV_PAGES); -- /* GMD2 */ -- for (q = 6; q < pse_port_num_queues[FE_PSE_PORT_GDM2]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0); -- /* GMD3 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM3]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q, -- PSE_QUEUE_RSV_PAGES); -- /* PPE1 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE1]; q++) { -- if (q < pse_port_num_queues[FE_PSE_PORT_PPE1]) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, -- PSE_QUEUE_RSV_PAGES); -- else -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0); -- } -- /* CDM2 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM2]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q, -- PSE_QUEUE_RSV_PAGES); -- /* CDM3 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0); -- /* CDM4 */ -- for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, -- PSE_QUEUE_RSV_PAGES); -- /* PPE2 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { -- if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, -- PSE_QUEUE_RSV_PAGES); -- else -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); -- } -- /* GMD4 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q, -- PSE_QUEUE_RSV_PAGES); -- /* CDM5 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM5]; q++) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q, -- PSE_QUEUE_RSV_PAGES); --} -- --static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth) --{ -- int i; -- -- for (i = 0; i < AIROHA_FE_MC_MAX_VLAN_TABLE; i++) { -- int err, j; -- u32 val; -- -- airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); -- -- val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | -- MC_VLAN_CFG_TABLE_SEL_MASK | MC_VLAN_CFG_RW_MASK; -- airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); -- err = read_poll_timeout(airoha_fe_rr, val, -- val & MC_VLAN_CFG_CMD_DONE_MASK, -- USEC_PER_MSEC, 5 * USEC_PER_MSEC, -- false, eth, REG_MC_VLAN_CFG); -- if (err) -- return err; -- -- for (j = 0; j < AIROHA_FE_MC_MAX_VLAN_PORT; j++) { -- airoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0); -- -- val = FIELD_PREP(MC_VLAN_CFG_TABLE_ID_MASK, i) | -- FIELD_PREP(MC_VLAN_CFG_PORT_ID_MASK, j) | -- MC_VLAN_CFG_RW_MASK; -- airoha_fe_wr(eth, REG_MC_VLAN_CFG, val); -- err = read_poll_timeout(airoha_fe_rr, val, -- val & MC_VLAN_CFG_CMD_DONE_MASK, -- USEC_PER_MSEC, -- 5 * USEC_PER_MSEC, false, eth, -- REG_MC_VLAN_CFG); -- if (err) -- return err; -- } -- } -- -- return 0; --} -- --static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) --{ -- /* CDM1_CRSN_QSEL */ -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_22 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), -- CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_08 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), -- CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_21 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), -- CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_24 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), -- CDM_CRSN_QSEL_Q6)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_25 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), -- CDM_CRSN_QSEL_Q1)); -- /* CDM2_CRSN_QSEL */ -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_08 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), -- CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_21 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), -- CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_22 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), -- CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_24 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), -- CDM_CRSN_QSEL_Q6)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_25 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), -- CDM_CRSN_QSEL_Q1)); --} -- --static int airoha_fe_init(struct airoha_eth *eth) --{ -- airoha_fe_maccr_init(eth); -- -- /* PSE IQ reserve */ -- airoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK, -- FIELD_PREP(PSE_IQ_RES1_P2_MASK, 0x10)); -- airoha_fe_rmw(eth, REG_PSE_IQ_REV2, -- PSE_IQ_RES2_P5_MASK | PSE_IQ_RES2_P4_MASK, -- FIELD_PREP(PSE_IQ_RES2_P5_MASK, 0x40) | -- FIELD_PREP(PSE_IQ_RES2_P4_MASK, 0x34)); -- -- /* enable FE copy engine for MC/KA/DPI */ -- airoha_fe_wr(eth, REG_FE_PCE_CFG, -- PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); -- /* set vip queue selection to ring 1 */ -- airoha_fe_rmw(eth, REG_CDM1_FWD_CFG, CDM1_VIP_QSEL_MASK, -- FIELD_PREP(CDM1_VIP_QSEL_MASK, 0x4)); -- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_VIP_QSEL_MASK, -- FIELD_PREP(CDM2_VIP_QSEL_MASK, 0x4)); -- /* set GDM4 source interface offset to 8 */ -- airoha_fe_rmw(eth, REG_GDM4_SRC_PORT_SET, -- GDM4_SPORT_OFF2_MASK | -- GDM4_SPORT_OFF1_MASK | -- GDM4_SPORT_OFF0_MASK, -- FIELD_PREP(GDM4_SPORT_OFF2_MASK, 8) | -- FIELD_PREP(GDM4_SPORT_OFF1_MASK, 8) | -- FIELD_PREP(GDM4_SPORT_OFF0_MASK, 8)); -- -- /* set PSE Page as 128B */ -- airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, -- FE_DMA_GLO_L2_SPACE_MASK | FE_DMA_GLO_PG_SZ_MASK, -- FIELD_PREP(FE_DMA_GLO_L2_SPACE_MASK, 2) | -- FE_DMA_GLO_PG_SZ_MASK); -- airoha_fe_wr(eth, REG_FE_RST_GLO_CFG, -- FE_RST_CORE_MASK | FE_RST_GDM3_MBI_ARB_MASK | -- FE_RST_GDM4_MBI_ARB_MASK); -- usleep_range(1000, 2000); -- -- /* connect RxRing1 and RxRing15 to PSE Port0 OQ-1 -- * connect other rings to PSE Port0 OQ-0 -- */ -- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4)); -- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28)); -- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4)); -- airoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28)); -- -- airoha_fe_vip_setup(eth); -- airoha_fe_pse_ports_init(eth); -- -- airoha_fe_set(eth, REG_GDM_MISC_CFG, -- GDM2_RDM_ACK_WAIT_PREF_MASK | -- GDM2_CHN_VLD_MODE_MASK); -- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, -- FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); -- -- /* init fragment and assemble Force Port */ -- /* NPU Core-3, NPU Bridge Channel-3 */ -- airoha_fe_rmw(eth, REG_IP_FRAG_FP, -- IP_FRAGMENT_PORT_MASK | IP_FRAGMENT_NBQ_MASK, -- FIELD_PREP(IP_FRAGMENT_PORT_MASK, 6) | -- FIELD_PREP(IP_FRAGMENT_NBQ_MASK, 3)); -- /* QDMA LAN, RX Ring-22 */ -- airoha_fe_rmw(eth, REG_IP_FRAG_FP, -- IP_ASSEMBLE_PORT_MASK | IP_ASSEMBLE_NBQ_MASK, -- FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | -- FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); -- -- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); -- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); -- -- airoha_fe_crsn_qsel_init(eth); -- -- airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK); -- airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); -- -- /* default aging mode for mbi unlock issue */ -- airoha_fe_rmw(eth, REG_GDM2_CHN_RLS, -- MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, -- FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | -- FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); -- -- /* disable IFC by default */ -- airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); -- -- /* enable 1:N vlan action, init vlan table */ -- airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); -- -- return airoha_fe_mc_vlan_clear(eth); --} -- --static int airoha_qdma_fill_rx_queue(struct airoha_queue *q) --{ -- enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); -- struct airoha_qdma *qdma = q->qdma; -- struct airoha_eth *eth = qdma->eth; -- int qid = q - &qdma->q_rx[0]; -- int nframes = 0; -- -- while (q->queued < q->ndesc - 1) { -- struct airoha_queue_entry *e = &q->entry[q->head]; -- struct airoha_qdma_desc *desc = &q->desc[q->head]; -- struct page *page; -- int offset; -- u32 val; -- -- page = page_pool_dev_alloc_frag(q->page_pool, &offset, -- q->buf_size); -- if (!page) -- break; -- -- q->head = (q->head + 1) % q->ndesc; -- q->queued++; -- nframes++; -- -- e->buf = page_address(page) + offset; -- e->dma_addr = page_pool_get_dma_addr(page) + offset; -- e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); -- -- dma_sync_single_for_device(eth->dev, e->dma_addr, e->dma_len, -- dir); -- -- val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); -- WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); -- WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr)); -- val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, q->head); -- WRITE_ONCE(desc->data, cpu_to_le32(val)); -- WRITE_ONCE(desc->msg0, 0); -- WRITE_ONCE(desc->msg1, 0); -- WRITE_ONCE(desc->msg2, 0); -- WRITE_ONCE(desc->msg3, 0); -- -- airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), -- RX_RING_CPU_IDX_MASK, -- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); -- } -- -- return nframes; --} -- --static int airoha_qdma_get_gdm_port(struct airoha_eth *eth, -- struct airoha_qdma_desc *desc) --{ -- u32 port, sport, msg1 = le32_to_cpu(desc->msg1); -- -- sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); -- switch (sport) { -- case 0x10 ... 0x13: -- port = 0; -- break; -- case 0x2 ... 0x4: -- port = sport - 1; -- break; -- default: -- return -EINVAL; -- } -- -- return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; --} -- --static int airoha_qdma_rx_process(struct airoha_queue *q, int budget) --{ -- enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); -- struct airoha_qdma *qdma = q->qdma; -- struct airoha_eth *eth = qdma->eth; -- int qid = q - &qdma->q_rx[0]; -- int done = 0; -- -- while (done < budget) { -- struct airoha_queue_entry *e = &q->entry[q->tail]; -- struct airoha_qdma_desc *desc = &q->desc[q->tail]; -- dma_addr_t dma_addr = le32_to_cpu(desc->addr); -- u32 desc_ctrl = le32_to_cpu(desc->ctrl); -- struct sk_buff *skb; -- int len, p; -- -- if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) -- break; -- -- if (!dma_addr) -- break; -- -- len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); -- if (!len) -- break; -- -- q->tail = (q->tail + 1) % q->ndesc; -- q->queued--; -- -- dma_sync_single_for_cpu(eth->dev, dma_addr, -- SKB_WITH_OVERHEAD(q->buf_size), dir); -- -- p = airoha_qdma_get_gdm_port(eth, desc); -- if (p < 0 || !eth->ports[p]) { -- page_pool_put_full_page(q->page_pool, -- virt_to_head_page(e->buf), -- true); -- continue; -- } -- -- skb = napi_build_skb(e->buf, q->buf_size); -- if (!skb) { -- page_pool_put_full_page(q->page_pool, -- virt_to_head_page(e->buf), -- true); -- break; -- } -- -- skb_reserve(skb, 2); -- __skb_put(skb, len); -- skb_mark_for_recycle(skb); -- skb->dev = eth->ports[p]->dev; -- skb->protocol = eth_type_trans(skb, skb->dev); -- skb->ip_summed = CHECKSUM_UNNECESSARY; -- skb_record_rx_queue(skb, qid); -- napi_gro_receive(&q->napi, skb); -- -- done++; -- } -- airoha_qdma_fill_rx_queue(q); -- -- return done; --} -- --static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) --{ -- struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); -- int cur, done = 0; -- -- do { -- cur = airoha_qdma_rx_process(q, budget - done); -- done += cur; -- } while (cur && done < budget); -- -- if (done < budget && napi_complete(napi)) -- airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1, -- RX_DONE_INT_MASK); -- -- return done; --} -- --static int airoha_qdma_init_rx_queue(struct airoha_queue *q, -- struct airoha_qdma *qdma, int ndesc) --{ -- const struct page_pool_params pp_params = { -- .order = 0, -- .pool_size = 256, -- .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, -- .dma_dir = DMA_FROM_DEVICE, -- .max_len = PAGE_SIZE, -- .nid = NUMA_NO_NODE, -- .dev = qdma->eth->dev, -- .napi = &q->napi, -- }; -- struct airoha_eth *eth = qdma->eth; -- int qid = q - &qdma->q_rx[0], thr; -- dma_addr_t dma_addr; -- -- q->buf_size = PAGE_SIZE / 2; -- q->qdma = qdma; -- -- q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry), -- GFP_KERNEL); -- if (!q->entry) -- return -ENOMEM; -- -- q->desc = dmam_alloc_coherent(eth->dev, ndesc * sizeof(*q->desc), -- &dma_addr, GFP_KERNEL); -- if (!q->desc) -- return -ENOMEM; -- -- q->page_pool = page_pool_create(&pp_params); -- if (IS_ERR(q->page_pool)) { -- int err = PTR_ERR(q->page_pool); -- -- q->page_pool = NULL; -- return err; -- } -- -- q->ndesc = ndesc; -- netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll); -- -- airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr); -- airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), -- RX_RING_SIZE_MASK, -- FIELD_PREP(RX_RING_SIZE_MASK, ndesc)); -- -- thr = clamp(ndesc >> 3, 1, 32); -- airoha_qdma_rmw(qdma, REG_RX_RING_SIZE(qid), RX_RING_THR_MASK, -- FIELD_PREP(RX_RING_THR_MASK, thr)); -- airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, -- FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); -- -- airoha_qdma_fill_rx_queue(q); -- -- return 0; --} -- --static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q) --{ -- struct airoha_qdma *qdma = q->qdma; -- struct airoha_eth *eth = qdma->eth; -- int qid = q - &qdma->q_rx[0]; -- -- while (q->queued) { -- struct airoha_queue_entry *e = &q->entry[q->tail]; -- struct airoha_qdma_desc *desc = &q->desc[q->tail]; -- struct page *page = virt_to_head_page(e->buf); -- -- dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len, -- page_pool_get_dma_dir(q->page_pool)); -- page_pool_put_full_page(q->page_pool, page, false); -- /* Reset DMA descriptor */ -- WRITE_ONCE(desc->ctrl, 0); -- WRITE_ONCE(desc->addr, 0); -- WRITE_ONCE(desc->data, 0); -- WRITE_ONCE(desc->msg0, 0); -- WRITE_ONCE(desc->msg1, 0); -- WRITE_ONCE(desc->msg2, 0); -- WRITE_ONCE(desc->msg3, 0); -- -- q->tail = (q->tail + 1) % q->ndesc; -- q->queued--; -- } -- -- q->head = q->tail; -- /* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is -- * empty. -- */ -- airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK, -- FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); -- airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, -- FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail)); --} -- --static int airoha_qdma_init_rx(struct airoha_qdma *qdma) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- int err; -- -- if (!(RX_DONE_INT_MASK & BIT(i))) { -- /* rx-queue not binded to irq */ -- continue; -- } -- -- err = airoha_qdma_init_rx_queue(&qdma->q_rx[i], qdma, -- RX_DSCP_NUM(i)); -- if (err) -- return err; -- } -- -- return 0; --} -- --static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget) --{ -- struct airoha_tx_irq_queue *irq_q; -- int id, done = 0, irq_queued; -- struct airoha_qdma *qdma; -- struct airoha_eth *eth; -- u32 status, head; -- -- irq_q = container_of(napi, struct airoha_tx_irq_queue, napi); -- qdma = irq_q->qdma; -- id = irq_q - &qdma->q_tx_irq[0]; -- eth = qdma->eth; -- -- status = airoha_qdma_rr(qdma, REG_IRQ_STATUS(id)); -- head = FIELD_GET(IRQ_HEAD_IDX_MASK, status); -- head = head % irq_q->size; -- irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status); -- -- while (irq_queued > 0 && done < budget) { -- u32 qid, val = irq_q->q[head]; -- struct airoha_qdma_desc *desc; -- struct airoha_queue_entry *e; -- struct airoha_queue *q; -- u32 index, desc_ctrl; -- struct sk_buff *skb; -- -- if (val == 0xff) -- break; -- -- irq_q->q[head] = 0xff; /* mark as done */ -- head = (head + 1) % irq_q->size; -- irq_queued--; -- done++; -- -- qid = FIELD_GET(IRQ_RING_IDX_MASK, val); -- if (qid >= ARRAY_SIZE(qdma->q_tx)) -- continue; -- -- q = &qdma->q_tx[qid]; -- if (!q->ndesc) -- continue; -- -- index = FIELD_GET(IRQ_DESC_IDX_MASK, val); -- if (index >= q->ndesc) -- continue; -- -- spin_lock_bh(&q->lock); -- -- if (!q->queued) -- goto unlock; -- -- desc = &q->desc[index]; -- desc_ctrl = le32_to_cpu(desc->ctrl); -- -- if (!(desc_ctrl & QDMA_DESC_DONE_MASK) && -- !(desc_ctrl & QDMA_DESC_DROP_MASK)) -- goto unlock; -- -- e = &q->entry[index]; -- skb = e->skb; -- -- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, -- DMA_TO_DEVICE); -- memset(e, 0, sizeof(*e)); -- WRITE_ONCE(desc->msg0, 0); -- WRITE_ONCE(desc->msg1, 0); -- q->queued--; -- -- /* completion ring can report out-of-order indexes if hw QoS -- * is enabled and packets with different priority are queued -- * to same DMA ring. Take into account possible out-of-order -- * reports incrementing DMA ring tail pointer -- */ -- while (q->tail != q->head && !q->entry[q->tail].dma_addr) -- q->tail = (q->tail + 1) % q->ndesc; -- -- if (skb) { -- u16 queue = skb_get_queue_mapping(skb); -- struct netdev_queue *txq; -- -- txq = netdev_get_tx_queue(skb->dev, queue); -- netdev_tx_completed_queue(txq, 1, skb->len); -- if (netif_tx_queue_stopped(txq) && -- q->ndesc - q->queued >= q->free_thr) -- netif_tx_wake_queue(txq); -- -- dev_kfree_skb_any(skb); -- } --unlock: -- spin_unlock_bh(&q->lock); -- } -- -- if (done) { -- int i, len = done >> 7; -- -- for (i = 0; i < len; i++) -- airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), -- IRQ_CLEAR_LEN_MASK, 0x80); -- airoha_qdma_rmw(qdma, REG_IRQ_CLEAR_LEN(id), -- IRQ_CLEAR_LEN_MASK, (done & 0x7f)); -- } -- -- if (done < budget && napi_complete(napi)) -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, -- TX_DONE_INT_MASK(id)); -- -- return done; --} -- --static int airoha_qdma_init_tx_queue(struct airoha_queue *q, -- struct airoha_qdma *qdma, int size) --{ -- struct airoha_eth *eth = qdma->eth; -- int i, qid = q - &qdma->q_tx[0]; -- dma_addr_t dma_addr; -- -- spin_lock_init(&q->lock); -- q->ndesc = size; -- q->qdma = qdma; -- q->free_thr = 1 + MAX_SKB_FRAGS; -- -- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), -- GFP_KERNEL); -- if (!q->entry) -- return -ENOMEM; -- -- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), -- &dma_addr, GFP_KERNEL); -- if (!q->desc) -- return -ENOMEM; -- -- for (i = 0; i < q->ndesc; i++) { -- u32 val; -- -- val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); -- WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); -- } -- -- /* xmit ring drop default setting */ -- airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), -- TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK); -- -- airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); -- airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, -- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); -- airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, -- FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head)); -- -- return 0; --} -- --static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q, -- struct airoha_qdma *qdma, int size) --{ -- int id = irq_q - &qdma->q_tx_irq[0]; -- struct airoha_eth *eth = qdma->eth; -- dma_addr_t dma_addr; -- -- netif_napi_add_tx(eth->napi_dev, &irq_q->napi, -- airoha_qdma_tx_napi_poll); -- irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32), -- &dma_addr, GFP_KERNEL); -- if (!irq_q->q) -- return -ENOMEM; -- -- memset(irq_q->q, 0xff, size * sizeof(u32)); -- irq_q->size = size; -- irq_q->qdma = qdma; -- -- airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr); -- airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK, -- FIELD_PREP(TX_IRQ_DEPTH_MASK, size)); -- airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_THR_MASK, -- FIELD_PREP(TX_IRQ_THR_MASK, 1)); -- -- return 0; --} -- --static int airoha_qdma_init_tx(struct airoha_qdma *qdma) --{ -- int i, err; -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { -- err = airoha_qdma_tx_irq_init(&qdma->q_tx_irq[i], qdma, -- IRQ_QUEUE_LEN(i)); -- if (err) -- return err; -- } -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -- err = airoha_qdma_init_tx_queue(&qdma->q_tx[i], qdma, -- TX_DSCP_NUM); -- if (err) -- return err; -- } -- -- return 0; --} -- --static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) --{ -- struct airoha_eth *eth = q->qdma->eth; -- -- spin_lock_bh(&q->lock); -- while (q->queued) { -- struct airoha_queue_entry *e = &q->entry[q->tail]; -- -- dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, -- DMA_TO_DEVICE); -- dev_kfree_skb_any(e->skb); -- e->skb = NULL; -- -- q->tail = (q->tail + 1) % q->ndesc; -- q->queued--; -- } -- spin_unlock_bh(&q->lock); --} -- --static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) --{ -- struct airoha_eth *eth = qdma->eth; -- dma_addr_t dma_addr; -- u32 status; -- int size; -- -- size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); -- qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr, -- GFP_KERNEL); -- if (!qdma->hfwd.desc) -- return -ENOMEM; -- -- airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); -- -- size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; -- qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr, -- GFP_KERNEL); -- if (!qdma->hfwd.q) -- return -ENOMEM; -- -- airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); -- -- airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, -- HW_FWD_DSCP_PAYLOAD_SIZE_MASK, -- FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); -- airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK, -- FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128)); -- airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, -- LMGR_INIT_START | LMGR_SRAM_MODE_MASK | -- HW_FWD_DESC_NUM_MASK, -- FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | -- LMGR_INIT_START); -- -- return read_poll_timeout(airoha_qdma_rr, status, -- !(status & LMGR_INIT_START), USEC_PER_MSEC, -- 30 * USEC_PER_MSEC, true, qdma, -- REG_LMGR_INIT_CFG); --} -- --static void airoha_qdma_init_qos(struct airoha_qdma *qdma) --{ -- airoha_qdma_clear(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_SCALE_MASK); -- airoha_qdma_set(qdma, REG_TXWRR_MODE_CFG, TWRR_WEIGHT_BASE_MASK); -- -- airoha_qdma_clear(qdma, REG_PSE_BUF_USAGE_CFG, -- PSE_BUF_ESTIMATE_EN_MASK); -- -- airoha_qdma_set(qdma, REG_EGRESS_RATE_METER_CFG, -- EGRESS_RATE_METER_EN_MASK | -- EGRESS_RATE_METER_EQ_RATE_EN_MASK); -- /* 2047us x 31 = 63.457ms */ -- airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, -- EGRESS_RATE_METER_WINDOW_SZ_MASK, -- FIELD_PREP(EGRESS_RATE_METER_WINDOW_SZ_MASK, 0x1f)); -- airoha_qdma_rmw(qdma, REG_EGRESS_RATE_METER_CFG, -- EGRESS_RATE_METER_TIMESLICE_MASK, -- FIELD_PREP(EGRESS_RATE_METER_TIMESLICE_MASK, 0x7ff)); -- -- /* ratelimit init */ -- airoha_qdma_set(qdma, REG_GLB_TRTCM_CFG, GLB_TRTCM_EN_MASK); -- /* fast-tick 25us */ -- airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_FAST_TICK_MASK, -- FIELD_PREP(GLB_FAST_TICK_MASK, 25)); -- airoha_qdma_rmw(qdma, REG_GLB_TRTCM_CFG, GLB_SLOW_TICK_RATIO_MASK, -- FIELD_PREP(GLB_SLOW_TICK_RATIO_MASK, 40)); -- -- airoha_qdma_set(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_TRTCM_EN_MASK); -- airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, EGRESS_FAST_TICK_MASK, -- FIELD_PREP(EGRESS_FAST_TICK_MASK, 25)); -- airoha_qdma_rmw(qdma, REG_EGRESS_TRTCM_CFG, -- EGRESS_SLOW_TICK_RATIO_MASK, -- FIELD_PREP(EGRESS_SLOW_TICK_RATIO_MASK, 40)); -- -- airoha_qdma_set(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_TRTCM_EN_MASK); -- airoha_qdma_clear(qdma, REG_INGRESS_TRTCM_CFG, -- INGRESS_TRTCM_MODE_MASK); -- airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, INGRESS_FAST_TICK_MASK, -- FIELD_PREP(INGRESS_FAST_TICK_MASK, 125)); -- airoha_qdma_rmw(qdma, REG_INGRESS_TRTCM_CFG, -- INGRESS_SLOW_TICK_RATIO_MASK, -- FIELD_PREP(INGRESS_SLOW_TICK_RATIO_MASK, 8)); -- -- airoha_qdma_set(qdma, REG_SLA_TRTCM_CFG, SLA_TRTCM_EN_MASK); -- airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_FAST_TICK_MASK, -- FIELD_PREP(SLA_FAST_TICK_MASK, 25)); -- airoha_qdma_rmw(qdma, REG_SLA_TRTCM_CFG, SLA_SLOW_TICK_RATIO_MASK, -- FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40)); --} -- --static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma) --{ -- int i; -- -- for (i = 0; i < AIROHA_NUM_QOS_CHANNELS; i++) { -- /* Tx-cpu transferred count */ -- airoha_qdma_wr(qdma, REG_CNTR_VAL(i << 1), 0); -- airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), -- CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | -- CNTR_ALL_DSCP_RING_EN_MASK | -- FIELD_PREP(CNTR_CHAN_MASK, i)); -- /* Tx-fwd transferred count */ -- airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0); -- airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1), -- CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK | -- CNTR_ALL_DSCP_RING_EN_MASK | -- FIELD_PREP(CNTR_SRC_MASK, 1) | -- FIELD_PREP(CNTR_CHAN_MASK, i)); -- } --} -- --static int airoha_qdma_hw_init(struct airoha_qdma *qdma) --{ -- int i; -- -- /* clear pending irqs */ -- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) -- airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); -- -- /* setup irqs */ -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK); -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK); -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK); -- -- /* setup irq binding */ -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -- if (!qdma->q_tx[i].ndesc) -- continue; -- -- if (TX_RING_IRQ_BLOCKING_MAP_MASK & BIT(i)) -- airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(i), -- TX_RING_IRQ_BLOCKING_CFG_MASK); -- else -- airoha_qdma_clear(qdma, REG_TX_RING_BLOCKING(i), -- TX_RING_IRQ_BLOCKING_CFG_MASK); -- } -- -- airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG, -- GLOBAL_CFG_RX_2B_OFFSET_MASK | -- FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) | -- GLOBAL_CFG_CPU_TXR_RR_MASK | -- GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK | -- GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK | -- GLOBAL_CFG_MULTICAST_EN_MASK | -- GLOBAL_CFG_IRQ0_EN_MASK | GLOBAL_CFG_IRQ1_EN_MASK | -- GLOBAL_CFG_TX_WB_DONE_MASK | -- FIELD_PREP(GLOBAL_CFG_MAX_ISSUE_NUM_MASK, 2)); -- -- airoha_qdma_init_qos(qdma); -- -- /* disable qdma rx delay interrupt */ -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- if (!qdma->q_rx[i].ndesc) -- continue; -- -- airoha_qdma_clear(qdma, REG_RX_DELAY_INT_IDX(i), -- RX_DELAY_INT_MASK); -- } -- -- airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG, -- TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN); -- airoha_qdma_init_qos_stats(qdma); -- -- return 0; --} -- --static irqreturn_t airoha_irq_handler(int irq, void *dev_instance) --{ -- struct airoha_qdma *qdma = dev_instance; -- u32 intr[ARRAY_SIZE(qdma->irqmask)]; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) { -- intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i)); -- intr[i] &= qdma->irqmask[i]; -- airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]); -- } -- -- if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state)) -- return IRQ_NONE; -- -- if (intr[1] & RX_DONE_INT_MASK) { -- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1, -- RX_DONE_INT_MASK); -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- if (!qdma->q_rx[i].ndesc) -- continue; -- -- if (intr[1] & BIT(i)) -- napi_schedule(&qdma->q_rx[i].napi); -- } -- } -- -- if (intr[0] & INT_TX_MASK) { -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { -- if (!(intr[0] & TX_DONE_INT_MASK(i))) -- continue; -- -- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, -- TX_DONE_INT_MASK(i)); -- napi_schedule(&qdma->q_tx_irq[i].napi); -- } -- } -- -- return IRQ_HANDLED; --} -- --static int airoha_qdma_init(struct platform_device *pdev, -- struct airoha_eth *eth, -- struct airoha_qdma *qdma) --{ -- int err, id = qdma - ð->qdma[0]; -- const char *res; -- -- spin_lock_init(&qdma->irq_lock); -- qdma->eth = eth; -- -- res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id); -- if (!res) -- return -ENOMEM; -- -- qdma->regs = devm_platform_ioremap_resource_byname(pdev, res); -- if (IS_ERR(qdma->regs)) -- return dev_err_probe(eth->dev, PTR_ERR(qdma->regs), -- "failed to iomap qdma%d regs\n", id); -- -- qdma->irq = platform_get_irq(pdev, 4 * id); -- if (qdma->irq < 0) -- return qdma->irq; -- -- err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler, -- IRQF_SHARED, KBUILD_MODNAME, qdma); -- if (err) -- return err; -- -- err = airoha_qdma_init_rx(qdma); -- if (err) -- return err; -- -- err = airoha_qdma_init_tx(qdma); -- if (err) -- return err; -- -- err = airoha_qdma_init_hfwd_queues(qdma); -- if (err) -- return err; -- -- return airoha_qdma_hw_init(qdma); --} -- --static int airoha_hw_init(struct platform_device *pdev, -- struct airoha_eth *eth) --{ -- int err, i; -- -- /* disable xsi */ -- err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), -- eth->xsi_rsts); -- if (err) -- return err; -- -- err = reset_control_bulk_assert(ARRAY_SIZE(eth->rsts), eth->rsts); -- if (err) -- return err; -- -- msleep(20); -- err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts); -- if (err) -- return err; -- -- msleep(20); -- err = airoha_fe_init(eth); -- if (err) -- return err; -- -- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { -- err = airoha_qdma_init(pdev, eth, ð->qdma[i]); -- if (err) -- return err; -- } -- -- set_bit(DEV_STATE_INITIALIZED, ð->state); -- -- return 0; --} -- --static void airoha_hw_cleanup(struct airoha_qdma *qdma) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- if (!qdma->q_rx[i].ndesc) -- continue; -- -- netif_napi_del(&qdma->q_rx[i].napi); -- airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); -- if (qdma->q_rx[i].page_pool) -- page_pool_destroy(qdma->q_rx[i].page_pool); -- } -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -- netif_napi_del(&qdma->q_tx_irq[i].napi); -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -- if (!qdma->q_tx[i].ndesc) -- continue; -- -- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -- } --} -- --static void airoha_qdma_start_napi(struct airoha_qdma *qdma) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -- napi_enable(&qdma->q_tx_irq[i].napi); -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- if (!qdma->q_rx[i].ndesc) -- continue; -- -- napi_enable(&qdma->q_rx[i].napi); -- } --} -- --static void airoha_qdma_stop_napi(struct airoha_qdma *qdma) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -- napi_disable(&qdma->q_tx_irq[i].napi); -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- if (!qdma->q_rx[i].ndesc) -- continue; -- -- napi_disable(&qdma->q_rx[i].napi); -- } --} -- --static void airoha_update_hw_stats(struct airoha_gdm_port *port) --{ -- struct airoha_eth *eth = port->qdma->eth; -- u32 val, i = 0; -- -- spin_lock(&port->stats.lock); -- u64_stats_update_begin(&port->stats.syncp); -- -- /* TX */ -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id)); -- port->stats.tx_ok_pkts += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id)); -- port->stats.tx_ok_pkts += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id)); -- port->stats.tx_ok_bytes += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id)); -- port->stats.tx_ok_bytes += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id)); -- port->stats.tx_drops += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id)); -- port->stats.tx_broadcast += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id)); -- port->stats.tx_multicast += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id)); -- port->stats.tx_len[i] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id)); -- port->stats.tx_len[i++] += val; -- -- /* RX */ -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id)); -- port->stats.rx_ok_pkts += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id)); -- port->stats.rx_ok_pkts += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id)); -- port->stats.rx_ok_bytes += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id)); -- port->stats.rx_ok_bytes += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id)); -- port->stats.rx_drops += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id)); -- port->stats.rx_broadcast += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id)); -- port->stats.rx_multicast += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id)); -- port->stats.rx_errors += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id)); -- port->stats.rx_crc_error += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id)); -- port->stats.rx_over_errors += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id)); -- port->stats.rx_fragment += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id)); -- port->stats.rx_jabber += val; -- -- i = 0; -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id)); -- port->stats.rx_len[i] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -- -- val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id)); -- port->stats.rx_len[i++] += val; -- -- /* reset mib counters */ -- airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id), -- FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK); -- -- u64_stats_update_end(&port->stats.syncp); -- spin_unlock(&port->stats.lock); --} -- --static int airoha_dev_open(struct net_device *dev) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_qdma *qdma = port->qdma; -- int err; -- -- netif_tx_start_all_queues(dev); -- err = airoha_set_gdm_ports(qdma->eth, true); -- if (err) -- return err; -- -- if (netdev_uses_dsa(dev)) -- airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), -- GDM_STAG_EN_MASK); -- else -- airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), -- GDM_STAG_EN_MASK); -- -- airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, -- GLOBAL_CFG_TX_DMA_EN_MASK | -- GLOBAL_CFG_RX_DMA_EN_MASK); -- -- return 0; --} -- --static int airoha_dev_stop(struct net_device *dev) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_qdma *qdma = port->qdma; -- int i, err; -- -- netif_tx_disable(dev); -- err = airoha_set_gdm_ports(qdma->eth, false); -- if (err) -- return err; -- -- airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, -- GLOBAL_CFG_TX_DMA_EN_MASK | -- GLOBAL_CFG_RX_DMA_EN_MASK); -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -- if (!qdma->q_tx[i].ndesc) -- continue; -- -- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -- netdev_tx_reset_subqueue(dev, i); -- } -- -- return 0; --} -- --static int airoha_dev_set_macaddr(struct net_device *dev, void *p) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- int err; -- -- err = eth_mac_addr(dev, p); -- if (err) -- return err; -- -- airoha_set_macaddr(port, dev->dev_addr); -- -- return 0; --} -- --static int airoha_dev_init(struct net_device *dev) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- -- airoha_set_macaddr(port, dev->dev_addr); -- -- return 0; --} -- --static void airoha_dev_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *storage) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- unsigned int start; -- -- airoha_update_hw_stats(port); -- do { -- start = u64_stats_fetch_begin(&port->stats.syncp); -- storage->rx_packets = port->stats.rx_ok_pkts; -- storage->tx_packets = port->stats.tx_ok_pkts; -- storage->rx_bytes = port->stats.rx_ok_bytes; -- storage->tx_bytes = port->stats.tx_ok_bytes; -- storage->multicast = port->stats.rx_multicast; -- storage->rx_errors = port->stats.rx_errors; -- storage->rx_dropped = port->stats.rx_drops; -- storage->tx_dropped = port->stats.tx_drops; -- storage->rx_crc_errors = port->stats.rx_crc_error; -- storage->rx_over_errors = port->stats.rx_over_errors; -- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); --} -- --static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, -- struct net_device *sb_dev) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- int queue, channel; -- -- /* For dsa device select QoS channel according to the dsa user port -- * index, rely on port id otherwise. Select QoS queue based on the -- * skb priority. -- */ -- channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; -- channel = channel % AIROHA_NUM_QOS_CHANNELS; -- queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ -- queue = channel * AIROHA_NUM_QOS_QUEUES + queue; -- -- return queue < dev->num_tx_queues ? queue : 0; --} -- --static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, -- struct net_device *dev) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; -- u32 msg0, msg1, len = skb_headlen(skb); -- struct airoha_qdma *qdma = port->qdma; -- struct netdev_queue *txq; -- struct airoha_queue *q; -- void *data = skb->data; -- int i, qid; -- u16 index; -- u8 fport; -- -- qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); -- msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, -- qid / AIROHA_NUM_QOS_QUEUES) | -- FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, -- qid % AIROHA_NUM_QOS_QUEUES); -- if (skb->ip_summed == CHECKSUM_PARTIAL) -- msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | -- FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | -- FIELD_PREP(QDMA_ETH_TXMSG_ICO_MASK, 1); -- -- /* TSO: fill MSS info in tcp checksum field */ -- if (skb_is_gso(skb)) { -- if (skb_cow_head(skb, 0)) -- goto error; -- -- if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | -- SKB_GSO_TCPV6)) { -- __be16 csum = cpu_to_be16(skb_shinfo(skb)->gso_size); -- -- tcp_hdr(skb)->check = (__force __sum16)csum; -- msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1); -- } -- } -- -- fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; -- msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | -- FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); -- -- q = &qdma->q_tx[qid]; -- if (WARN_ON_ONCE(!q->ndesc)) -- goto error; -- -- spin_lock_bh(&q->lock); -- -- txq = netdev_get_tx_queue(dev, qid); -- if (q->queued + nr_frags > q->ndesc) { -- /* not enough space in the queue */ -- netif_tx_stop_queue(txq); -- spin_unlock_bh(&q->lock); -- return NETDEV_TX_BUSY; -- } -- -- index = q->head; -- for (i = 0; i < nr_frags; i++) { -- struct airoha_qdma_desc *desc = &q->desc[index]; -- struct airoha_queue_entry *e = &q->entry[index]; -- skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -- dma_addr_t addr; -- u32 val; -- -- addr = dma_map_single(dev->dev.parent, data, len, -- DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(dev->dev.parent, addr))) -- goto error_unmap; -- -- index = (index + 1) % q->ndesc; -- -- val = FIELD_PREP(QDMA_DESC_LEN_MASK, len); -- if (i < nr_frags - 1) -- val |= FIELD_PREP(QDMA_DESC_MORE_MASK, 1); -- WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); -- WRITE_ONCE(desc->addr, cpu_to_le32(addr)); -- val = FIELD_PREP(QDMA_DESC_NEXT_ID_MASK, index); -- WRITE_ONCE(desc->data, cpu_to_le32(val)); -- WRITE_ONCE(desc->msg0, cpu_to_le32(msg0)); -- WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); -- WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); -- -- e->skb = i ? NULL : skb; -- e->dma_addr = addr; -- e->dma_len = len; -- -- data = skb_frag_address(frag); -- len = skb_frag_size(frag); -- } -- -- q->head = index; -- q->queued += i; -- -- skb_tx_timestamp(skb); -- netdev_tx_sent_queue(txq, skb->len); -- -- if (netif_xmit_stopped(txq) || !netdev_xmit_more()) -- airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), -- TX_RING_CPU_IDX_MASK, -- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); -- -- if (q->ndesc - q->queued < q->free_thr) -- netif_tx_stop_queue(txq); -- -- spin_unlock_bh(&q->lock); -- -- return NETDEV_TX_OK; -- --error_unmap: -- for (i--; i >= 0; i--) { -- index = (q->head + i) % q->ndesc; -- dma_unmap_single(dev->dev.parent, q->entry[index].dma_addr, -- q->entry[index].dma_len, DMA_TO_DEVICE); -- } -- -- spin_unlock_bh(&q->lock); --error: -- dev_kfree_skb_any(skb); -- dev->stats.tx_dropped++; -- -- return NETDEV_TX_OK; --} -- --static void airoha_ethtool_get_drvinfo(struct net_device *dev, -- struct ethtool_drvinfo *info) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_eth *eth = port->qdma->eth; -- -- strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); -- strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); --} -- --static void airoha_ethtool_get_mac_stats(struct net_device *dev, -- struct ethtool_eth_mac_stats *stats) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- unsigned int start; -- -- airoha_update_hw_stats(port); -- do { -- start = u64_stats_fetch_begin(&port->stats.syncp); -- stats->MulticastFramesXmittedOK = port->stats.tx_multicast; -- stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; -- stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; -- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); --} -- --static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = { -- { 0, 64 }, -- { 65, 127 }, -- { 128, 255 }, -- { 256, 511 }, -- { 512, 1023 }, -- { 1024, 1518 }, -- { 1519, 10239 }, -- {}, --}; -- --static void --airoha_ethtool_get_rmon_stats(struct net_device *dev, -- struct ethtool_rmon_stats *stats, -- const struct ethtool_rmon_hist_range **ranges) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_hw_stats *hw_stats = &port->stats; -- unsigned int start; -- -- BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != -- ARRAY_SIZE(hw_stats->tx_len) + 1); -- BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != -- ARRAY_SIZE(hw_stats->rx_len) + 1); -- -- *ranges = airoha_ethtool_rmon_ranges; -- airoha_update_hw_stats(port); -- do { -- int i; -- -- start = u64_stats_fetch_begin(&port->stats.syncp); -- stats->fragments = hw_stats->rx_fragment; -- stats->jabbers = hw_stats->rx_jabber; -- for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1; -- i++) { -- stats->hist[i] = hw_stats->rx_len[i]; -- stats->hist_tx[i] = hw_stats->tx_len[i]; -- } -- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); --} -- --static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port, -- int channel, enum tx_sched_mode mode, -- const u16 *weights, u8 n_weights) --{ -- int i; -- -- for (i = 0; i < AIROHA_NUM_TX_RING; i++) -- airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), -- TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)); -- -- for (i = 0; i < n_weights; i++) { -- u32 status; -- int err; -- -- airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, -- TWRR_RW_CMD_MASK | -- FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) | -- FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) | -- FIELD_PREP(TWRR_VALUE_MASK, weights[i])); -- err = read_poll_timeout(airoha_qdma_rr, status, -- status & TWRR_RW_CMD_DONE, -- USEC_PER_MSEC, 10 * USEC_PER_MSEC, -- true, port->qdma, -- REG_TXWRR_WEIGHT_CFG); -- if (err) -- return err; -- } -- -- airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), -- CHAN_QOS_MODE_MASK(channel), -- mode << __ffs(CHAN_QOS_MODE_MASK(channel))); -- -- return 0; --} -- --static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port, -- int channel) --{ -- static const u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -- -- return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w, -- ARRAY_SIZE(w)); --} -- --static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port, -- int channel, -- struct tc_ets_qopt_offload *opt) --{ -- struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; -- enum tx_sched_mode mode = TC_SCH_SP; -- u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -- int i, nstrict = 0, nwrr, qidx; -- -- if (p->bands > AIROHA_NUM_QOS_QUEUES) -- return -EINVAL; -- -- for (i = 0; i < p->bands; i++) { -- if (!p->quanta[i]) -- nstrict++; -- } -- -- /* this configuration is not supported by the hw */ -- if (nstrict == AIROHA_NUM_QOS_QUEUES - 1) -- return -EINVAL; -- -- /* EN7581 SoC supports fixed QoS band priority where WRR queues have -- * lowest priorities with respect to SP ones. -- * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn -- */ -- nwrr = p->bands - nstrict; -- qidx = nstrict && nwrr ? nstrict : 0; -- for (i = 1; i <= p->bands; i++) { -- if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) -- return -EINVAL; -- -- qidx = i == nwrr ? 0 : qidx + 1; -- } -- -- for (i = 0; i < nwrr; i++) -- w[i] = p->weights[nstrict + i]; -- -- if (!nstrict) -- mode = TC_SCH_WRR8; -- else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) -- mode = nstrict + 1; -- -- return airoha_qdma_set_chan_tx_sched(port, channel, mode, w, -- ARRAY_SIZE(w)); --} -- --static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port, -- int channel, -- struct tc_ets_qopt_offload *opt) --{ -- u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, -- REG_CNTR_VAL(channel << 1)); -- u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, -- REG_CNTR_VAL((channel << 1) + 1)); -- u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + -- (fwd_tx_packets - port->fwd_tx_packets); -- _bstats_update(opt->stats.bstats, 0, tx_packets); -- -- port->cpu_tx_packets = cpu_tx_packets; -- port->fwd_tx_packets = fwd_tx_packets; -- -- return 0; --} -- --static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, -- struct tc_ets_qopt_offload *opt) --{ -- int channel = TC_H_MAJ(opt->handle) >> 16; -- -- if (opt->parent == TC_H_ROOT) -- return -EINVAL; -- -- switch (opt->command) { -- case TC_ETS_REPLACE: -- return airoha_qdma_set_tx_ets_sched(port, channel, opt); -- case TC_ETS_DESTROY: -- /* PRIO is default qdisc scheduler */ -- return airoha_qdma_set_tx_prio_sched(port, channel); -- case TC_ETS_STATS: -- return airoha_qdma_get_tx_ets_stats(port, channel, opt); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, -- u32 addr, enum trtcm_param_type param, -- enum trtcm_mode_type mode, -- u32 *val_low, u32 *val_high) --{ -- u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); -- u32 val, config = FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | -- FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | -- FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | -- FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); -- -- airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -- if (read_poll_timeout(airoha_qdma_rr, val, -- val & TRTCM_PARAM_RW_DONE_MASK, -- USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, -- qdma, REG_TRTCM_CFG_PARAM(addr))) -- return -ETIMEDOUT; -- -- *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); -- if (val_high) -- *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); -- -- return 0; --} -- --static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel, -- u32 addr, enum trtcm_param_type param, -- enum trtcm_mode_type mode, u32 val) --{ -- u32 idx = QDMA_METER_IDX(channel), group = QDMA_METER_GROUP(channel); -- u32 config = TRTCM_PARAM_RW_MASK | -- FIELD_PREP(TRTCM_PARAM_TYPE_MASK, param) | -- FIELD_PREP(TRTCM_METER_GROUP_MASK, group) | -- FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) | -- FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode); -- -- airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); -- airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -- -- return read_poll_timeout(airoha_qdma_rr, val, -- val & TRTCM_PARAM_RW_DONE_MASK, -- USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, -- qdma, REG_TRTCM_CFG_PARAM(addr)); --} -- --static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel, -- u32 addr, enum trtcm_mode_type mode, -- bool enable, u32 enable_mask) --{ -- u32 val; -- -- if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -- mode, &val, NULL)) -- return -EINVAL; -- -- val = enable ? val | enable_mask : val & ~enable_mask; -- -- return airoha_qdma_set_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -- mode, val); --} -- --static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma, -- int channel, u32 addr, -- enum trtcm_mode_type mode, -- u32 rate_val, u32 bucket_size) --{ -- u32 val, config, tick, unit, rate, rate_frac; -- int err; -- -- if (airoha_qdma_get_trtcm_param(qdma, channel, addr, TRTCM_MISC_MODE, -- mode, &config, NULL)) -- return -EINVAL; -- -- val = airoha_qdma_rr(qdma, addr); -- tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); -- if (config & TRTCM_TICK_SEL) -- tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); -- if (!tick) -- return -EINVAL; -- -- unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; -- if (!unit) -- return -EINVAL; -- -- rate = rate_val / unit; -- rate_frac = rate_val % unit; -- rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; -- rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | -- FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); -- -- err = airoha_qdma_set_trtcm_param(qdma, channel, addr, -- TRTCM_TOKEN_RATE_MODE, mode, rate); -- if (err) -- return err; -- -- val = max_t(u32, bucket_size, MIN_TOKEN_SIZE); -- val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); -- -- return airoha_qdma_set_trtcm_param(qdma, channel, addr, -- TRTCM_BUCKETSIZE_SHIFT_MODE, -- mode, val); --} -- --static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port, -- int channel, u32 rate, -- u32 bucket_size) --{ -- int i, err; -- -- for (i = 0; i <= TRTCM_PEAK_MODE; i++) { -- err = airoha_qdma_set_trtcm_config(port->qdma, channel, -- REG_EGRESS_TRTCM_CFG, i, -- !!rate, TRTCM_METER_MODE); -- if (err) -- return err; -- -- err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, -- REG_EGRESS_TRTCM_CFG, -- i, rate, bucket_size); -- if (err) -- return err; -- } -- -- return 0; --} -- --static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port, -- struct tc_htb_qopt_offload *opt) --{ -- u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -- u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ -- struct net_device *dev = port->dev; -- int num_tx_queues = dev->real_num_tx_queues; -- int err; -- -- if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { -- NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); -- return -EINVAL; -- } -- -- err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); -- if (err) { -- NL_SET_ERR_MSG_MOD(opt->extack, -- "failed configuring htb offload"); -- return err; -- } -- -- if (opt->command == TC_HTB_NODE_MODIFY) -- return 0; -- -- err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); -- if (err) { -- airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); -- NL_SET_ERR_MSG_MOD(opt->extack, -- "failed setting real_num_tx_queues"); -- return err; -- } -- -- set_bit(channel, port->qos_sq_bmap); -- opt->qid = AIROHA_NUM_TX_RING + channel; -- -- return 0; --} -- --static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) --{ -- struct net_device *dev = port->dev; -- -- netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); -- airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0); -- clear_bit(queue, port->qos_sq_bmap); --} -- --static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port, -- struct tc_htb_qopt_offload *opt) --{ -- u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -- -- if (!test_bit(channel, port->qos_sq_bmap)) { -- NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -- return -EINVAL; -- } -- -- airoha_tc_remove_htb_queue(port, channel); -- -- return 0; --} -- --static int airoha_tc_htb_destroy(struct airoha_gdm_port *port) --{ -- int q; -- -- for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) -- airoha_tc_remove_htb_queue(port, q); -- -- return 0; --} -- --static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port, -- struct tc_htb_qopt_offload *opt) --{ -- u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -- -- if (!test_bit(channel, port->qos_sq_bmap)) { -- NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -- return -EINVAL; -- } -- -- opt->qid = channel; -- -- return 0; --} -- --static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port, -- struct tc_htb_qopt_offload *opt) --{ -- switch (opt->command) { -- case TC_HTB_CREATE: -- break; -- case TC_HTB_DESTROY: -- return airoha_tc_htb_destroy(port); -- case TC_HTB_NODE_MODIFY: -- case TC_HTB_LEAF_ALLOC_QUEUE: -- return airoha_tc_htb_alloc_leaf_queue(port, opt); -- case TC_HTB_LEAF_DEL: -- case TC_HTB_LEAF_DEL_LAST: -- case TC_HTB_LEAF_DEL_LAST_FORCE: -- return airoha_tc_htb_delete_leaf_queue(port, opt); -- case TC_HTB_LEAF_QUERY_QUEUE: -- return airoha_tc_get_htb_get_leaf_queue(port, opt); -- default: -- return -EOPNOTSUPP; -- } -- -- return 0; --} -- --static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, -- void *type_data) --{ -- struct airoha_gdm_port *port = netdev_priv(dev); -- -- switch (type) { -- case TC_SETUP_QDISC_ETS: -- return airoha_tc_setup_qdisc_ets(port, type_data); -- case TC_SETUP_QDISC_HTB: -- return airoha_tc_setup_qdisc_htb(port, type_data); -- default: -- return -EOPNOTSUPP; -- } --} -- --static const struct net_device_ops airoha_netdev_ops = { -- .ndo_init = airoha_dev_init, -- .ndo_open = airoha_dev_open, -- .ndo_stop = airoha_dev_stop, -- .ndo_select_queue = airoha_dev_select_queue, -- .ndo_start_xmit = airoha_dev_xmit, -- .ndo_get_stats64 = airoha_dev_get_stats64, -- .ndo_set_mac_address = airoha_dev_set_macaddr, -- .ndo_setup_tc = airoha_dev_tc_setup, --}; -- --static const struct ethtool_ops airoha_ethtool_ops = { -- .get_drvinfo = airoha_ethtool_get_drvinfo, -- .get_eth_mac_stats = airoha_ethtool_get_mac_stats, -- .get_rmon_stats = airoha_ethtool_get_rmon_stats, --}; -- --static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) --{ -- const __be32 *id_ptr = of_get_property(np, "reg", NULL); -- struct airoha_gdm_port *port; -- struct airoha_qdma *qdma; -- struct net_device *dev; -- int err, index; -- u32 id; -- -- if (!id_ptr) { -- dev_err(eth->dev, "missing gdm port id\n"); -- return -EINVAL; -- } -- -- id = be32_to_cpup(id_ptr); -- index = id - 1; -- -- if (!id || id > ARRAY_SIZE(eth->ports)) { -- dev_err(eth->dev, "invalid gdm port id: %d\n", id); -- return -EINVAL; -- } -- -- if (eth->ports[index]) { -- dev_err(eth->dev, "duplicate gdm port id: %d\n", id); -- return -EINVAL; -- } -- -- dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), -- AIROHA_NUM_NETDEV_TX_RINGS, -- AIROHA_NUM_RX_RING); -- if (!dev) { -- dev_err(eth->dev, "alloc_etherdev failed\n"); -- return -ENOMEM; -- } -- -- qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA]; -- dev->netdev_ops = &airoha_netdev_ops; -- dev->ethtool_ops = &airoha_ethtool_ops; -- dev->max_mtu = AIROHA_MAX_MTU; -- dev->watchdog_timeo = 5 * HZ; -- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | -- NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | -- NETIF_F_SG | NETIF_F_TSO | -- NETIF_F_HW_TC; -- dev->features |= dev->hw_features; -- dev->dev.of_node = np; -- dev->irq = qdma->irq; -- SET_NETDEV_DEV(dev, eth->dev); -- -- /* reserve hw queues for HTB offloading */ -- err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING); -- if (err) -- return err; -- -- err = of_get_ethdev_address(np, dev); -- if (err) { -- if (err == -EPROBE_DEFER) -- return err; -- -- eth_hw_addr_random(dev); -- dev_info(eth->dev, "generated random MAC address %pM\n", -- dev->dev_addr); -- } -- -- port = netdev_priv(dev); -- u64_stats_init(&port->stats.syncp); -- spin_lock_init(&port->stats.lock); -- port->qdma = qdma; -- port->dev = dev; -- port->id = id; -- eth->ports[index] = port; -- -- return register_netdev(dev); --} -- --static int airoha_probe(struct platform_device *pdev) --{ -- struct device_node *np; -- struct airoha_eth *eth; -- int i, err; -- -- eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); -- if (!eth) -- return -ENOMEM; -- -- eth->dev = &pdev->dev; -- -- err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); -- if (err) { -- dev_err(eth->dev, "failed configuring DMA mask\n"); -- return err; -- } -- -- eth->fe_regs = devm_platform_ioremap_resource_byname(pdev, "fe"); -- if (IS_ERR(eth->fe_regs)) -- return dev_err_probe(eth->dev, PTR_ERR(eth->fe_regs), -- "failed to iomap fe regs\n"); -- -- eth->rsts[0].id = "fe"; -- eth->rsts[1].id = "pdma"; -- eth->rsts[2].id = "qdma"; -- err = devm_reset_control_bulk_get_exclusive(eth->dev, -- ARRAY_SIZE(eth->rsts), -- eth->rsts); -- if (err) { -- dev_err(eth->dev, "failed to get bulk reset lines\n"); -- return err; -- } -- -- eth->xsi_rsts[0].id = "xsi-mac"; -- eth->xsi_rsts[1].id = "hsi0-mac"; -- eth->xsi_rsts[2].id = "hsi1-mac"; -- eth->xsi_rsts[3].id = "hsi-mac"; -- eth->xsi_rsts[4].id = "xfp-mac"; -- err = devm_reset_control_bulk_get_exclusive(eth->dev, -- ARRAY_SIZE(eth->xsi_rsts), -- eth->xsi_rsts); -- if (err) { -- dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); -- return err; -- } -- -- eth->napi_dev = alloc_netdev_dummy(0); -- if (!eth->napi_dev) -- return -ENOMEM; -- -- /* Enable threaded NAPI by default */ -- eth->napi_dev->threaded = true; -- strscpy(eth->napi_dev->name, "qdma_eth", sizeof(eth->napi_dev->name)); -- platform_set_drvdata(pdev, eth); -- -- err = airoha_hw_init(pdev, eth); -- if (err) -- goto error_hw_cleanup; -- -- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -- airoha_qdma_start_napi(ð->qdma[i]); -- -- for_each_child_of_node(pdev->dev.of_node, np) { -- if (!of_device_is_compatible(np, "airoha,eth-mac")) -- continue; -- -- if (!of_device_is_available(np)) -- continue; -- -- err = airoha_alloc_gdm_port(eth, np); -- if (err) { -- of_node_put(np); -- goto error_napi_stop; -- } -- } -- -- return 0; -- --error_napi_stop: -- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -- airoha_qdma_stop_napi(ð->qdma[i]); --error_hw_cleanup: -- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -- airoha_hw_cleanup(ð->qdma[i]); -- -- for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -- struct airoha_gdm_port *port = eth->ports[i]; -- -- if (port && port->dev->reg_state == NETREG_REGISTERED) -- unregister_netdev(port->dev); -- } -- free_netdev(eth->napi_dev); -- platform_set_drvdata(pdev, NULL); -- -- return err; --} -- --static void airoha_remove(struct platform_device *pdev) --{ -- struct airoha_eth *eth = platform_get_drvdata(pdev); -- int i; -- -- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { -- airoha_qdma_stop_napi(ð->qdma[i]); -- airoha_hw_cleanup(ð->qdma[i]); -- } -- -- for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -- struct airoha_gdm_port *port = eth->ports[i]; -- -- if (!port) -- continue; -- -- unregister_netdev(port->dev); -- } -- free_netdev(eth->napi_dev); -- -- platform_set_drvdata(pdev, NULL); --} -- --static const struct of_device_id of_airoha_match[] = { -- { .compatible = "airoha,en7581-eth" }, -- { /* sentinel */ } --}; --MODULE_DEVICE_TABLE(of, of_airoha_match); -- --static struct platform_driver airoha_driver = { -- .probe = airoha_probe, -- .remove_new = airoha_remove, -- .driver = { -- .name = KBUILD_MODNAME, -- .of_match_table = of_airoha_match, -- }, --}; --module_platform_driver(airoha_driver); -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Lorenzo Bianconi "); --MODULE_DESCRIPTION("Ethernet driver for Airoha SoC"); diff --git a/target/linux/airoha/patches-6.12/048-02-v6.15-net-airoha-Move-definitions-in-airoha_eth.h.patch b/target/linux/airoha/patches-6.12/048-02-v6.15-net-airoha-Move-definitions-in-airoha_eth.h.patch deleted file mode 100644 index 85391281a25..00000000000 --- a/target/linux/airoha/patches-6.12/048-02-v6.15-net-airoha-Move-definitions-in-airoha_eth.h.patch +++ /dev/null @@ -1,538 +0,0 @@ -From b38f4ff0ceacd6ce8d333a8dc90f405a040968d3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:10 +0100 -Subject: [PATCH 02/15] net: airoha: Move definitions in airoha_eth.h - -Move common airoha_eth definitions in airoha_eth.h in order to reuse -them for Packet Processor Engine (PPE) codebase. -PPE module is used to enable support for flowtable hw offloading in -airoha_eth driver. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 240 +--------------------- - drivers/net/ethernet/airoha/airoha_eth.h | 251 +++++++++++++++++++++++ - 2 files changed, 252 insertions(+), 239 deletions(-) - create mode 100644 drivers/net/ethernet/airoha/airoha_eth.h - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3,14 +3,9 @@ - * Copyright (c) 2024 AIROHA Inc - * Author: Lorenzo Bianconi - */ --#include --#include --#include --#include - #include - #include - #include --#include - #include - #include - #include -@@ -18,35 +13,7 @@ - #include - #include - --#define AIROHA_MAX_NUM_GDM_PORTS 1 --#define AIROHA_MAX_NUM_QDMA 2 --#define AIROHA_MAX_NUM_RSTS 3 --#define AIROHA_MAX_NUM_XSI_RSTS 5 --#define AIROHA_MAX_MTU 2000 --#define AIROHA_MAX_PACKET_SIZE 2048 --#define AIROHA_NUM_QOS_CHANNELS 4 --#define AIROHA_NUM_QOS_QUEUES 8 --#define AIROHA_NUM_TX_RING 32 --#define AIROHA_NUM_RX_RING 32 --#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ -- AIROHA_NUM_QOS_CHANNELS) --#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 --#define AIROHA_FE_MC_MAX_VLAN_PORT 16 --#define AIROHA_NUM_TX_IRQ 2 --#define HW_DSCP_NUM 2048 --#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) --#define TX_DSCP_NUM 1024 --#define RX_DSCP_NUM(_n) \ -- ((_n) == 2 ? 128 : \ -- (_n) == 11 ? 128 : \ -- (_n) == 15 ? 128 : \ -- (_n) == 0 ? 1024 : 16) -- --#define PSE_RSV_PAGES 128 --#define PSE_QUEUE_RSV_PAGES 64 -- --#define QDMA_METER_IDX(_n) ((_n) & 0xff) --#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) -+#include "airoha_eth.h" - - /* FE */ - #define PSE_BASE 0x0100 -@@ -706,211 +673,6 @@ struct airoha_qdma_fwd_desc { - __le32 rsv1; - }; - --enum { -- QDMA_INT_REG_IDX0, -- QDMA_INT_REG_IDX1, -- QDMA_INT_REG_IDX2, -- QDMA_INT_REG_IDX3, -- QDMA_INT_REG_IDX4, -- QDMA_INT_REG_MAX --}; -- --enum { -- XSI_PCIE0_PORT, -- XSI_PCIE1_PORT, -- XSI_USB_PORT, -- XSI_AE_PORT, -- XSI_ETH_PORT, --}; -- --enum { -- XSI_PCIE0_VIP_PORT_MASK = BIT(22), -- XSI_PCIE1_VIP_PORT_MASK = BIT(23), -- XSI_USB_VIP_PORT_MASK = BIT(25), -- XSI_ETH_VIP_PORT_MASK = BIT(24), --}; -- --enum { -- DEV_STATE_INITIALIZED, --}; -- --enum { -- CDM_CRSN_QSEL_Q1 = 1, -- CDM_CRSN_QSEL_Q5 = 5, -- CDM_CRSN_QSEL_Q6 = 6, -- CDM_CRSN_QSEL_Q15 = 15, --}; -- --enum { -- CRSN_08 = 0x8, -- CRSN_21 = 0x15, /* KA */ -- CRSN_22 = 0x16, /* hit bind and force route to CPU */ -- CRSN_24 = 0x18, -- CRSN_25 = 0x19, --}; -- --enum { -- FE_PSE_PORT_CDM1, -- FE_PSE_PORT_GDM1, -- FE_PSE_PORT_GDM2, -- FE_PSE_PORT_GDM3, -- FE_PSE_PORT_PPE1, -- FE_PSE_PORT_CDM2, -- FE_PSE_PORT_CDM3, -- FE_PSE_PORT_CDM4, -- FE_PSE_PORT_PPE2, -- FE_PSE_PORT_GDM4, -- FE_PSE_PORT_CDM5, -- FE_PSE_PORT_DROP = 0xf, --}; -- --enum tx_sched_mode { -- TC_SCH_WRR8, -- TC_SCH_SP, -- TC_SCH_WRR7, -- TC_SCH_WRR6, -- TC_SCH_WRR5, -- TC_SCH_WRR4, -- TC_SCH_WRR3, -- TC_SCH_WRR2, --}; -- --enum trtcm_param_type { -- TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ -- TRTCM_TOKEN_RATE_MODE, -- TRTCM_BUCKETSIZE_SHIFT_MODE, -- TRTCM_BUCKET_COUNTER_MODE, --}; -- --enum trtcm_mode_type { -- TRTCM_COMMIT_MODE, -- TRTCM_PEAK_MODE, --}; -- --enum trtcm_param { -- TRTCM_TICK_SEL = BIT(0), -- TRTCM_PKT_MODE = BIT(1), -- TRTCM_METER_MODE = BIT(2), --}; -- --#define MIN_TOKEN_SIZE 4096 --#define MAX_TOKEN_SIZE_OFFSET 17 --#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) --#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) -- --struct airoha_queue_entry { -- union { -- void *buf; -- struct sk_buff *skb; -- }; -- dma_addr_t dma_addr; -- u16 dma_len; --}; -- --struct airoha_queue { -- struct airoha_qdma *qdma; -- -- /* protect concurrent queue accesses */ -- spinlock_t lock; -- struct airoha_queue_entry *entry; -- struct airoha_qdma_desc *desc; -- u16 head; -- u16 tail; -- -- int queued; -- int ndesc; -- int free_thr; -- int buf_size; -- -- struct napi_struct napi; -- struct page_pool *page_pool; --}; -- --struct airoha_tx_irq_queue { -- struct airoha_qdma *qdma; -- -- struct napi_struct napi; -- -- int size; -- u32 *q; --}; -- --struct airoha_hw_stats { -- /* protect concurrent hw_stats accesses */ -- spinlock_t lock; -- struct u64_stats_sync syncp; -- -- /* get_stats64 */ -- u64 rx_ok_pkts; -- u64 tx_ok_pkts; -- u64 rx_ok_bytes; -- u64 tx_ok_bytes; -- u64 rx_multicast; -- u64 rx_errors; -- u64 rx_drops; -- u64 tx_drops; -- u64 rx_crc_error; -- u64 rx_over_errors; -- /* ethtool stats */ -- u64 tx_broadcast; -- u64 tx_multicast; -- u64 tx_len[7]; -- u64 rx_broadcast; -- u64 rx_fragment; -- u64 rx_jabber; -- u64 rx_len[7]; --}; -- --struct airoha_qdma { -- struct airoha_eth *eth; -- void __iomem *regs; -- -- /* protect concurrent irqmask accesses */ -- spinlock_t irq_lock; -- u32 irqmask[QDMA_INT_REG_MAX]; -- int irq; -- -- struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; -- -- struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; -- struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; -- -- /* descriptor and packet buffers for qdma hw forward */ -- struct { -- void *desc; -- void *q; -- } hfwd; --}; -- --struct airoha_gdm_port { -- struct airoha_qdma *qdma; -- struct net_device *dev; -- int id; -- -- struct airoha_hw_stats stats; -- -- DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); -- -- /* qos stats counters */ -- u64 cpu_tx_packets; -- u64 fwd_tx_packets; --}; -- --struct airoha_eth { -- struct device *dev; -- -- unsigned long state; -- void __iomem *fe_regs; -- -- struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; -- struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; -- -- struct net_device *napi_dev; -- -- struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; -- struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; --}; -- - static u32 airoha_rr(void __iomem *base, u32 offset) - { - return readl(base + offset); ---- /dev/null -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -0,0 +1,251 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#ifndef AIROHA_ETH_H -+#define AIROHA_ETH_H -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define AIROHA_MAX_NUM_GDM_PORTS 1 -+#define AIROHA_MAX_NUM_QDMA 2 -+#define AIROHA_MAX_NUM_RSTS 3 -+#define AIROHA_MAX_NUM_XSI_RSTS 5 -+#define AIROHA_MAX_MTU 2000 -+#define AIROHA_MAX_PACKET_SIZE 2048 -+#define AIROHA_NUM_QOS_CHANNELS 4 -+#define AIROHA_NUM_QOS_QUEUES 8 -+#define AIROHA_NUM_TX_RING 32 -+#define AIROHA_NUM_RX_RING 32 -+#define AIROHA_NUM_NETDEV_TX_RINGS (AIROHA_NUM_TX_RING + \ -+ AIROHA_NUM_QOS_CHANNELS) -+#define AIROHA_FE_MC_MAX_VLAN_TABLE 64 -+#define AIROHA_FE_MC_MAX_VLAN_PORT 16 -+#define AIROHA_NUM_TX_IRQ 2 -+#define HW_DSCP_NUM 2048 -+#define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) -+#define TX_DSCP_NUM 1024 -+#define RX_DSCP_NUM(_n) \ -+ ((_n) == 2 ? 128 : \ -+ (_n) == 11 ? 128 : \ -+ (_n) == 15 ? 128 : \ -+ (_n) == 0 ? 1024 : 16) -+ -+#define PSE_RSV_PAGES 128 -+#define PSE_QUEUE_RSV_PAGES 64 -+ -+#define QDMA_METER_IDX(_n) ((_n) & 0xff) -+#define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) -+ -+enum { -+ QDMA_INT_REG_IDX0, -+ QDMA_INT_REG_IDX1, -+ QDMA_INT_REG_IDX2, -+ QDMA_INT_REG_IDX3, -+ QDMA_INT_REG_IDX4, -+ QDMA_INT_REG_MAX -+}; -+ -+enum { -+ XSI_PCIE0_PORT, -+ XSI_PCIE1_PORT, -+ XSI_USB_PORT, -+ XSI_AE_PORT, -+ XSI_ETH_PORT, -+}; -+ -+enum { -+ XSI_PCIE0_VIP_PORT_MASK = BIT(22), -+ XSI_PCIE1_VIP_PORT_MASK = BIT(23), -+ XSI_USB_VIP_PORT_MASK = BIT(25), -+ XSI_ETH_VIP_PORT_MASK = BIT(24), -+}; -+ -+enum { -+ DEV_STATE_INITIALIZED, -+}; -+ -+enum { -+ CDM_CRSN_QSEL_Q1 = 1, -+ CDM_CRSN_QSEL_Q5 = 5, -+ CDM_CRSN_QSEL_Q6 = 6, -+ CDM_CRSN_QSEL_Q15 = 15, -+}; -+ -+enum { -+ CRSN_08 = 0x8, -+ CRSN_21 = 0x15, /* KA */ -+ CRSN_22 = 0x16, /* hit bind and force route to CPU */ -+ CRSN_24 = 0x18, -+ CRSN_25 = 0x19, -+}; -+ -+enum { -+ FE_PSE_PORT_CDM1, -+ FE_PSE_PORT_GDM1, -+ FE_PSE_PORT_GDM2, -+ FE_PSE_PORT_GDM3, -+ FE_PSE_PORT_PPE1, -+ FE_PSE_PORT_CDM2, -+ FE_PSE_PORT_CDM3, -+ FE_PSE_PORT_CDM4, -+ FE_PSE_PORT_PPE2, -+ FE_PSE_PORT_GDM4, -+ FE_PSE_PORT_CDM5, -+ FE_PSE_PORT_DROP = 0xf, -+}; -+ -+enum tx_sched_mode { -+ TC_SCH_WRR8, -+ TC_SCH_SP, -+ TC_SCH_WRR7, -+ TC_SCH_WRR6, -+ TC_SCH_WRR5, -+ TC_SCH_WRR4, -+ TC_SCH_WRR3, -+ TC_SCH_WRR2, -+}; -+ -+enum trtcm_param_type { -+ TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ -+ TRTCM_TOKEN_RATE_MODE, -+ TRTCM_BUCKETSIZE_SHIFT_MODE, -+ TRTCM_BUCKET_COUNTER_MODE, -+}; -+ -+enum trtcm_mode_type { -+ TRTCM_COMMIT_MODE, -+ TRTCM_PEAK_MODE, -+}; -+ -+enum trtcm_param { -+ TRTCM_TICK_SEL = BIT(0), -+ TRTCM_PKT_MODE = BIT(1), -+ TRTCM_METER_MODE = BIT(2), -+}; -+ -+#define MIN_TOKEN_SIZE 4096 -+#define MAX_TOKEN_SIZE_OFFSET 17 -+#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6) -+#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0) -+ -+struct airoha_queue_entry { -+ union { -+ void *buf; -+ struct sk_buff *skb; -+ }; -+ dma_addr_t dma_addr; -+ u16 dma_len; -+}; -+ -+struct airoha_queue { -+ struct airoha_qdma *qdma; -+ -+ /* protect concurrent queue accesses */ -+ spinlock_t lock; -+ struct airoha_queue_entry *entry; -+ struct airoha_qdma_desc *desc; -+ u16 head; -+ u16 tail; -+ -+ int queued; -+ int ndesc; -+ int free_thr; -+ int buf_size; -+ -+ struct napi_struct napi; -+ struct page_pool *page_pool; -+}; -+ -+struct airoha_tx_irq_queue { -+ struct airoha_qdma *qdma; -+ -+ struct napi_struct napi; -+ -+ int size; -+ u32 *q; -+}; -+ -+struct airoha_hw_stats { -+ /* protect concurrent hw_stats accesses */ -+ spinlock_t lock; -+ struct u64_stats_sync syncp; -+ -+ /* get_stats64 */ -+ u64 rx_ok_pkts; -+ u64 tx_ok_pkts; -+ u64 rx_ok_bytes; -+ u64 tx_ok_bytes; -+ u64 rx_multicast; -+ u64 rx_errors; -+ u64 rx_drops; -+ u64 tx_drops; -+ u64 rx_crc_error; -+ u64 rx_over_errors; -+ /* ethtool stats */ -+ u64 tx_broadcast; -+ u64 tx_multicast; -+ u64 tx_len[7]; -+ u64 rx_broadcast; -+ u64 rx_fragment; -+ u64 rx_jabber; -+ u64 rx_len[7]; -+}; -+ -+struct airoha_qdma { -+ struct airoha_eth *eth; -+ void __iomem *regs; -+ -+ /* protect concurrent irqmask accesses */ -+ spinlock_t irq_lock; -+ u32 irqmask[QDMA_INT_REG_MAX]; -+ int irq; -+ -+ struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; -+ -+ struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; -+ struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; -+ -+ /* descriptor and packet buffers for qdma hw forward */ -+ struct { -+ void *desc; -+ void *q; -+ } hfwd; -+}; -+ -+struct airoha_gdm_port { -+ struct airoha_qdma *qdma; -+ struct net_device *dev; -+ int id; -+ -+ struct airoha_hw_stats stats; -+ -+ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); -+ -+ /* qos stats counters */ -+ u64 cpu_tx_packets; -+ u64 fwd_tx_packets; -+}; -+ -+struct airoha_eth { -+ struct device *dev; -+ -+ unsigned long state; -+ void __iomem *fe_regs; -+ -+ struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; -+ struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; -+ -+ struct net_device *napi_dev; -+ -+ struct airoha_qdma qdma[AIROHA_MAX_NUM_QDMA]; -+ struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; -+}; -+ -+#endif /* AIROHA_ETH_H */ diff --git a/target/linux/airoha/patches-6.12/048-03-v6.15-net-airoha-Move-reg-write-utility-routines-in-airoha.patch b/target/linux/airoha/patches-6.12/048-03-v6.15-net-airoha-Move-reg-write-utility-routines-in-airoha.patch deleted file mode 100644 index bf24638ec91..00000000000 --- a/target/linux/airoha/patches-6.12/048-03-v6.15-net-airoha-Move-reg-write-utility-routines-in-airoha.patch +++ /dev/null @@ -1,101 +0,0 @@ -From e0758a8694fbaffdc72940774db295585e951119 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:11 +0100 -Subject: [PATCH 03/15] net: airoha: Move reg/write utility routines in - airoha_eth.h - -This is a preliminary patch to introduce flowtable hw offloading -support for airoha_eth driver. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 28 +++--------------------- - drivers/net/ethernet/airoha/airoha_eth.h | 26 ++++++++++++++++++++++ - 2 files changed, 29 insertions(+), 25 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -673,17 +673,17 @@ struct airoha_qdma_fwd_desc { - __le32 rsv1; - }; - --static u32 airoha_rr(void __iomem *base, u32 offset) -+u32 airoha_rr(void __iomem *base, u32 offset) - { - return readl(base + offset); - } - --static void airoha_wr(void __iomem *base, u32 offset, u32 val) -+void airoha_wr(void __iomem *base, u32 offset, u32 val) - { - writel(val, base + offset); - } - --static u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) -+u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) - { - val |= (airoha_rr(base, offset) & ~mask); - airoha_wr(base, offset, val); -@@ -691,28 +691,6 @@ static u32 airoha_rmw(void __iomem *base - return val; - } - --#define airoha_fe_rr(eth, offset) \ -- airoha_rr((eth)->fe_regs, (offset)) --#define airoha_fe_wr(eth, offset, val) \ -- airoha_wr((eth)->fe_regs, (offset), (val)) --#define airoha_fe_rmw(eth, offset, mask, val) \ -- airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) --#define airoha_fe_set(eth, offset, val) \ -- airoha_rmw((eth)->fe_regs, (offset), 0, (val)) --#define airoha_fe_clear(eth, offset, val) \ -- airoha_rmw((eth)->fe_regs, (offset), (val), 0) -- --#define airoha_qdma_rr(qdma, offset) \ -- airoha_rr((qdma)->regs, (offset)) --#define airoha_qdma_wr(qdma, offset, val) \ -- airoha_wr((qdma)->regs, (offset), (val)) --#define airoha_qdma_rmw(qdma, offset, mask, val) \ -- airoha_rmw((qdma)->regs, (offset), (mask), (val)) --#define airoha_qdma_set(qdma, offset, val) \ -- airoha_rmw((qdma)->regs, (offset), 0, (val)) --#define airoha_qdma_clear(qdma, offset, val) \ -- airoha_rmw((qdma)->regs, (offset), (val), 0) -- - static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, - u32 clear, u32 set) - { ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -248,4 +248,30 @@ struct airoha_eth { - struct airoha_gdm_port *ports[AIROHA_MAX_NUM_GDM_PORTS]; - }; - -+u32 airoha_rr(void __iomem *base, u32 offset); -+void airoha_wr(void __iomem *base, u32 offset, u32 val); -+u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val); -+ -+#define airoha_fe_rr(eth, offset) \ -+ airoha_rr((eth)->fe_regs, (offset)) -+#define airoha_fe_wr(eth, offset, val) \ -+ airoha_wr((eth)->fe_regs, (offset), (val)) -+#define airoha_fe_rmw(eth, offset, mask, val) \ -+ airoha_rmw((eth)->fe_regs, (offset), (mask), (val)) -+#define airoha_fe_set(eth, offset, val) \ -+ airoha_rmw((eth)->fe_regs, (offset), 0, (val)) -+#define airoha_fe_clear(eth, offset, val) \ -+ airoha_rmw((eth)->fe_regs, (offset), (val), 0) -+ -+#define airoha_qdma_rr(qdma, offset) \ -+ airoha_rr((qdma)->regs, (offset)) -+#define airoha_qdma_wr(qdma, offset, val) \ -+ airoha_wr((qdma)->regs, (offset), (val)) -+#define airoha_qdma_rmw(qdma, offset, mask, val) \ -+ airoha_rmw((qdma)->regs, (offset), (mask), (val)) -+#define airoha_qdma_set(qdma, offset, val) \ -+ airoha_rmw((qdma)->regs, (offset), 0, (val)) -+#define airoha_qdma_clear(qdma, offset, val) \ -+ airoha_rmw((qdma)->regs, (offset), (val), 0) -+ - #endif /* AIROHA_ETH_H */ diff --git a/target/linux/airoha/patches-6.12/048-04-v6.15-net-airoha-Move-register-definitions-in-airoha_regs..patch b/target/linux/airoha/patches-6.12/048-04-v6.15-net-airoha-Move-register-definitions-in-airoha_regs..patch deleted file mode 100644 index 3b2b8bfe5dc..00000000000 --- a/target/linux/airoha/patches-6.12/048-04-v6.15-net-airoha-Move-register-definitions-in-airoha_regs..patch +++ /dev/null @@ -1,1361 +0,0 @@ -From ec663d9a82bf4d16721f6b1fc29df4892ba6c088 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:12 +0100 -Subject: [PATCH 04/15] net: airoha: Move register definitions in airoha_regs.h - -Move common airoha_eth register definitions in airoha_regs.h in order -to reuse them for Packet Processor Engine (PPE) codebase. -PPE module is used to enable support for flowtable hw offloading in -airoha_eth driver. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 659 +-------------------- - drivers/net/ethernet/airoha/airoha_regs.h | 670 ++++++++++++++++++++++ - 2 files changed, 671 insertions(+), 658 deletions(-) - create mode 100644 drivers/net/ethernet/airoha/airoha_regs.h - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -13,666 +13,9 @@ - #include - #include - -+#include "airoha_regs.h" - #include "airoha_eth.h" - --/* FE */ --#define PSE_BASE 0x0100 --#define CSR_IFC_BASE 0x0200 --#define CDM1_BASE 0x0400 --#define GDM1_BASE 0x0500 --#define PPE1_BASE 0x0c00 -- --#define CDM2_BASE 0x1400 --#define GDM2_BASE 0x1500 -- --#define GDM3_BASE 0x1100 --#define GDM4_BASE 0x2500 -- --#define GDM_BASE(_n) \ -- ((_n) == 4 ? GDM4_BASE : \ -- (_n) == 3 ? GDM3_BASE : \ -- (_n) == 2 ? GDM2_BASE : GDM1_BASE) -- --#define REG_FE_DMA_GLO_CFG 0x0000 --#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) --#define FE_DMA_GLO_PG_SZ_MASK BIT(3) -- --#define REG_FE_RST_GLO_CFG 0x0004 --#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) --#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) --#define FE_RST_CORE_MASK BIT(0) -- --#define REG_FE_WAN_MAC_H 0x0030 --#define REG_FE_LAN_MAC_H 0x0040 -- --#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) --#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) -- --#define REG_FE_CDM1_OQ_MAP0 0x0050 --#define REG_FE_CDM1_OQ_MAP1 0x0054 --#define REG_FE_CDM1_OQ_MAP2 0x0058 --#define REG_FE_CDM1_OQ_MAP3 0x005c -- --#define REG_FE_PCE_CFG 0x0070 --#define PCE_DPI_EN_MASK BIT(2) --#define PCE_KA_EN_MASK BIT(1) --#define PCE_MC_EN_MASK BIT(0) -- --#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 --#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) --#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) --#define PSE_CFG_WR_EN_MASK BIT(8) --#define PSE_CFG_OQRSV_SEL_MASK BIT(0) -- --#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 --#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) -- --#define PSE_FQ_CFG 0x008c --#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) -- --#define REG_FE_PSE_BUF_SET 0x0090 --#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) --#define PSE_ALLRSV_MASK GENMASK(14, 0) -- --#define REG_PSE_SHARE_USED_THD 0x0094 --#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) --#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) -- --#define REG_GDM_MISC_CFG 0x0148 --#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) --#define GDM2_CHN_VLD_MODE_MASK BIT(5) -- --#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE --#define FE_IFC_EN_MASK BIT(0) -- --#define REG_FE_VIP_PORT_EN 0x01f0 --#define REG_FE_IFC_PORT_EN 0x01f4 -- --#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) --#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) -- --#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) --#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) --#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) -- --#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) --#define PATN_FCPU_EN_MASK BIT(7) --#define PATN_SWP_EN_MASK BIT(6) --#define PATN_DP_EN_MASK BIT(5) --#define PATN_SP_EN_MASK BIT(4) --#define PATN_TYPE_MASK GENMASK(3, 1) --#define PATN_EN_MASK BIT(0) -- --#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) --#define PATN_DP_MASK GENMASK(31, 16) --#define PATN_SP_MASK GENMASK(15, 0) -- --#define REG_CDM1_VLAN_CTRL CDM1_BASE --#define CDM1_VLAN_MASK GENMASK(31, 16) -- --#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) --#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) -- --#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) --#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ -- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -- --#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) --#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) --#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) -- --#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) --#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ -- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -- --#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) --#define GDM_DROP_CRC_ERR BIT(23) --#define GDM_IP4_CKSUM BIT(22) --#define GDM_TCP_CKSUM BIT(21) --#define GDM_UDP_CKSUM BIT(20) --#define GDM_UCFQ_MASK GENMASK(15, 12) --#define GDM_BCFQ_MASK GENMASK(11, 8) --#define GDM_MCFQ_MASK GENMASK(7, 4) --#define GDM_OCFQ_MASK GENMASK(3, 0) -- --#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) --#define GDM_INGRESS_FC_EN_MASK BIT(1) --#define GDM_STAG_EN_MASK BIT(0) -- --#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) --#define GDM_SHORT_LEN_MASK GENMASK(13, 0) --#define GDM_LONG_LEN_MASK GENMASK(29, 16) -- --#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) --#define FE_CPORT_PAD BIT(26) --#define FE_CPORT_PORT_XFC_MASK BIT(25) --#define FE_CPORT_QUEUE_XFC_MASK BIT(24) -- --#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) --#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) --#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) -- --#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) --#define FE_STRICT_RFC2819_MODE_MASK BIT(31) --#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) --#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) --#define FE_TX_MIB_ID_MASK GENMASK(15, 8) --#define FE_RX_MIB_ID_MASK GENMASK(7, 0) -- --#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) --#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) --#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) --#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) --#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) --#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) --#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) --#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) --#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) --#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) --#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) --#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) --#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) --#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) --#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) -- --#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) --#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) --#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) --#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) --#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) --#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) --#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) --#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) --#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) --#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) --#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) --#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) --#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) --#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) --#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) --#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) --#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) --#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) --#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) --#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) --#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) --#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) -- --#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) --#define PPE1_SRAM_TABLE_EN_MASK BIT(0) --#define PPE1_SRAM_HASH1_EN_MASK BIT(8) --#define PPE1_DRAM_TABLE_EN_MASK BIT(16) --#define PPE1_DRAM_HASH1_EN_MASK BIT(24) -- --#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) --#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) --#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) --#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) -- --#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) --#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) --#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) --#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) --#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) --#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) --#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) --#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) --#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) --#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) --#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) --#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) --#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) --#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) --#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) --#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) -- --#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) --#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) --#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) -- --#define REG_GDM3_FWD_CFG GDM3_BASE --#define GDM3_PAD_EN_MASK BIT(28) -- --#define REG_GDM4_FWD_CFG GDM4_BASE --#define GDM4_PAD_EN_MASK BIT(28) --#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) -- --#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) --#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) --#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) --#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) -- --#define REG_IP_FRAG_FP 0x2010 --#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) --#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) --#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) --#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) -- --#define REG_MC_VLAN_EN 0x2100 --#define MC_VLAN_EN_MASK BIT(0) -- --#define REG_MC_VLAN_CFG 0x2104 --#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) --#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) --#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) --#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) --#define MC_VLAN_CFG_RW_MASK BIT(0) -- --#define REG_MC_VLAN_DATA 0x2108 -- --#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 -- --/* QDMA */ --#define REG_QDMA_GLOBAL_CFG 0x0004 --#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) --#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) --#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) --#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) --#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) --#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) --#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) --#define GLOBAL_CFG_RESET_MASK BIT(23) --#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) --#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) --#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) --#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) --#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) --#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) --#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) --#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) --#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) --#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) --#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) --#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) --#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) --#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) --#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) -- --#define REG_FWD_DSCP_BASE 0x0010 --#define REG_FWD_BUF_BASE 0x0014 -- --#define REG_HW_FWD_DSCP_CFG 0x0018 --#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) --#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) --#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) -- --#define REG_INT_STATUS(_n) \ -- (((_n) == 4) ? 0x0730 : \ -- ((_n) == 3) ? 0x0724 : \ -- ((_n) == 2) ? 0x0720 : \ -- ((_n) == 1) ? 0x0024 : 0x0020) -- --#define REG_INT_ENABLE(_n) \ -- (((_n) == 4) ? 0x0750 : \ -- ((_n) == 3) ? 0x0744 : \ -- ((_n) == 2) ? 0x0740 : \ -- ((_n) == 1) ? 0x002c : 0x0028) -- --/* QDMA_CSR_INT_ENABLE1 */ --#define RX15_COHERENT_INT_MASK BIT(31) --#define RX14_COHERENT_INT_MASK BIT(30) --#define RX13_COHERENT_INT_MASK BIT(29) --#define RX12_COHERENT_INT_MASK BIT(28) --#define RX11_COHERENT_INT_MASK BIT(27) --#define RX10_COHERENT_INT_MASK BIT(26) --#define RX9_COHERENT_INT_MASK BIT(25) --#define RX8_COHERENT_INT_MASK BIT(24) --#define RX7_COHERENT_INT_MASK BIT(23) --#define RX6_COHERENT_INT_MASK BIT(22) --#define RX5_COHERENT_INT_MASK BIT(21) --#define RX4_COHERENT_INT_MASK BIT(20) --#define RX3_COHERENT_INT_MASK BIT(19) --#define RX2_COHERENT_INT_MASK BIT(18) --#define RX1_COHERENT_INT_MASK BIT(17) --#define RX0_COHERENT_INT_MASK BIT(16) --#define TX7_COHERENT_INT_MASK BIT(15) --#define TX6_COHERENT_INT_MASK BIT(14) --#define TX5_COHERENT_INT_MASK BIT(13) --#define TX4_COHERENT_INT_MASK BIT(12) --#define TX3_COHERENT_INT_MASK BIT(11) --#define TX2_COHERENT_INT_MASK BIT(10) --#define TX1_COHERENT_INT_MASK BIT(9) --#define TX0_COHERENT_INT_MASK BIT(8) --#define CNT_OVER_FLOW_INT_MASK BIT(7) --#define IRQ1_FULL_INT_MASK BIT(5) --#define IRQ1_INT_MASK BIT(4) --#define HWFWD_DSCP_LOW_INT_MASK BIT(3) --#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) --#define IRQ0_FULL_INT_MASK BIT(1) --#define IRQ0_INT_MASK BIT(0) -- --#define TX_DONE_INT_MASK(_n) \ -- ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ -- : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -- --#define INT_TX_MASK \ -- (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ -- IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -- --#define INT_IDX0_MASK \ -- (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ -- TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ -- TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ -- TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ -- RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ -- RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ -- RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ -- RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ -- RX15_COHERENT_INT_MASK | INT_TX_MASK) -- --/* QDMA_CSR_INT_ENABLE2 */ --#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) --#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) --#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) --#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) --#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) --#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) --#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) --#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) --#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) --#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) --#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) --#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) --#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) --#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) --#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) --#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) --#define RX15_DONE_INT_MASK BIT(15) --#define RX14_DONE_INT_MASK BIT(14) --#define RX13_DONE_INT_MASK BIT(13) --#define RX12_DONE_INT_MASK BIT(12) --#define RX11_DONE_INT_MASK BIT(11) --#define RX10_DONE_INT_MASK BIT(10) --#define RX9_DONE_INT_MASK BIT(9) --#define RX8_DONE_INT_MASK BIT(8) --#define RX7_DONE_INT_MASK BIT(7) --#define RX6_DONE_INT_MASK BIT(6) --#define RX5_DONE_INT_MASK BIT(5) --#define RX4_DONE_INT_MASK BIT(4) --#define RX3_DONE_INT_MASK BIT(3) --#define RX2_DONE_INT_MASK BIT(2) --#define RX1_DONE_INT_MASK BIT(1) --#define RX0_DONE_INT_MASK BIT(0) -- --#define RX_DONE_INT_MASK \ -- (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ -- RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ -- RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ -- RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ -- RX15_DONE_INT_MASK) --#define INT_IDX1_MASK \ -- (RX_DONE_INT_MASK | \ -- RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ -- RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ -- RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ -- RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ -- RX15_NO_CPU_DSCP_INT_MASK) -- --/* QDMA_CSR_INT_ENABLE5 */ --#define TX31_COHERENT_INT_MASK BIT(31) --#define TX30_COHERENT_INT_MASK BIT(30) --#define TX29_COHERENT_INT_MASK BIT(29) --#define TX28_COHERENT_INT_MASK BIT(28) --#define TX27_COHERENT_INT_MASK BIT(27) --#define TX26_COHERENT_INT_MASK BIT(26) --#define TX25_COHERENT_INT_MASK BIT(25) --#define TX24_COHERENT_INT_MASK BIT(24) --#define TX23_COHERENT_INT_MASK BIT(23) --#define TX22_COHERENT_INT_MASK BIT(22) --#define TX21_COHERENT_INT_MASK BIT(21) --#define TX20_COHERENT_INT_MASK BIT(20) --#define TX19_COHERENT_INT_MASK BIT(19) --#define TX18_COHERENT_INT_MASK BIT(18) --#define TX17_COHERENT_INT_MASK BIT(17) --#define TX16_COHERENT_INT_MASK BIT(16) --#define TX15_COHERENT_INT_MASK BIT(15) --#define TX14_COHERENT_INT_MASK BIT(14) --#define TX13_COHERENT_INT_MASK BIT(13) --#define TX12_COHERENT_INT_MASK BIT(12) --#define TX11_COHERENT_INT_MASK BIT(11) --#define TX10_COHERENT_INT_MASK BIT(10) --#define TX9_COHERENT_INT_MASK BIT(9) --#define TX8_COHERENT_INT_MASK BIT(8) -- --#define INT_IDX4_MASK \ -- (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ -- TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ -- TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ -- TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ -- TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ -- TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ -- TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ -- TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ -- TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ -- TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ -- TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ -- TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) -- --#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) -- --#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) --#define TX_IRQ_THR_MASK GENMASK(27, 16) --#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) -- --#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) --#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) -- --#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) --#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) --#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) -- --#define REG_TX_RING_BASE(_n) \ -- (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) -- --#define REG_TX_RING_BLOCKING(_n) \ -- (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) -- --#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) --#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) --#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) --#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) --#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) -- --#define REG_TX_CPU_IDX(_n) \ -- (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) -- --#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) -- --#define REG_TX_DMA_IDX(_n) \ -- (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) -- --#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) -- --#define IRQ_RING_IDX_MASK GENMASK(20, 16) --#define IRQ_DESC_IDX_MASK GENMASK(15, 0) -- --#define REG_RX_RING_BASE(_n) \ -- (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) -- --#define REG_RX_RING_SIZE(_n) \ -- (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) -- --#define RX_RING_THR_MASK GENMASK(31, 16) --#define RX_RING_SIZE_MASK GENMASK(15, 0) -- --#define REG_RX_CPU_IDX(_n) \ -- (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) -- --#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) -- --#define REG_RX_DMA_IDX(_n) \ -- (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) -- --#define REG_RX_DELAY_INT_IDX(_n) \ -- (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) -- --#define RX_DELAY_INT_MASK GENMASK(15, 0) -- --#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) -- --#define REG_INGRESS_TRTCM_CFG 0x0070 --#define INGRESS_TRTCM_EN_MASK BIT(31) --#define INGRESS_TRTCM_MODE_MASK BIT(30) --#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) -- --#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) --#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) -- --#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) --#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) -- --#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) --#define CNTR_EN_MASK BIT(31) --#define CNTR_ALL_CHAN_EN_MASK BIT(30) --#define CNTR_ALL_QUEUE_EN_MASK BIT(29) --#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) --#define CNTR_SRC_MASK GENMASK(27, 24) --#define CNTR_DSCP_RING_MASK GENMASK(20, 16) --#define CNTR_CHAN_MASK GENMASK(7, 3) --#define CNTR_QUEUE_MASK GENMASK(2, 0) -- --#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) -- --#define REG_LMGR_INIT_CFG 0x1000 --#define LMGR_INIT_START BIT(31) --#define LMGR_SRAM_MODE_MASK BIT(30) --#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) --#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) -- --#define REG_FWD_DSCP_LOW_THR 0x1004 --#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) -- --#define REG_EGRESS_RATE_METER_CFG 0x100c --#define EGRESS_RATE_METER_EN_MASK BIT(31) --#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) --#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) --#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) -- --#define REG_EGRESS_TRTCM_CFG 0x1010 --#define EGRESS_TRTCM_EN_MASK BIT(31) --#define EGRESS_TRTCM_MODE_MASK BIT(30) --#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) -- --#define TRTCM_PARAM_RW_MASK BIT(31) --#define TRTCM_PARAM_RW_DONE_MASK BIT(30) --#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) --#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) --#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) --#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) -- --#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) --#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) --#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) -- --#define REG_TXWRR_MODE_CFG 0x1020 --#define TWRR_WEIGHT_SCALE_MASK BIT(31) --#define TWRR_WEIGHT_BASE_MASK BIT(3) -- --#define REG_TXWRR_WEIGHT_CFG 0x1024 --#define TWRR_RW_CMD_MASK BIT(31) --#define TWRR_RW_CMD_DONE BIT(30) --#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) --#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) --#define TWRR_VALUE_MASK GENMASK(15, 0) -- --#define REG_PSE_BUF_USAGE_CFG 0x1028 --#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) -- --#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) --#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) -- --#define REG_GLB_TRTCM_CFG 0x1080 --#define GLB_TRTCM_EN_MASK BIT(31) --#define GLB_TRTCM_MODE_MASK BIT(30) --#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define GLB_FAST_TICK_MASK GENMASK(15, 0) -- --#define REG_TXQ_CNGST_CFG 0x10a0 --#define TXQ_CNGST_DROP_EN BIT(31) --#define TXQ_CNGST_DEI_DROP_EN BIT(30) -- --#define REG_SLA_TRTCM_CFG 0x1150 --#define SLA_TRTCM_EN_MASK BIT(31) --#define SLA_TRTCM_MODE_MASK BIT(30) --#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) --#define SLA_FAST_TICK_MASK GENMASK(15, 0) -- --/* CTRL */ --#define QDMA_DESC_DONE_MASK BIT(31) --#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ --#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ --#define QDMA_DESC_DEI_MASK BIT(25) --#define QDMA_DESC_NO_DROP_MASK BIT(24) --#define QDMA_DESC_LEN_MASK GENMASK(15, 0) --/* DATA */ --#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) --/* TX MSG0 */ --#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) --#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) --#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) --#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) --#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) --#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) --#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) --#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) --#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) --#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) --/* TX MSG1 */ --#define QDMA_ETH_TXMSG_NO_DROP BIT(31) --#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ --#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) --#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) --#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) --#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) --#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) --#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ --#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ -- --/* RX MSG1 */ --#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) --#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) --#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) --#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) --#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) --#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) --#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) --#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) --#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) -- --struct airoha_qdma_desc { -- __le32 rsv; -- __le32 ctrl; -- __le32 addr; -- __le32 data; -- __le32 msg0; -- __le32 msg1; -- __le32 msg2; -- __le32 msg3; --}; -- --/* CTRL0 */ --#define QDMA_FWD_DESC_CTX_MASK BIT(31) --#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) --#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) --#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) --/* CTRL1 */ --#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) --/* CTRL2 */ --#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) -- --struct airoha_qdma_fwd_desc { -- __le32 addr; -- __le32 ctrl0; -- __le32 ctrl1; -- __le32 ctrl2; -- __le32 msg0; -- __le32 msg1; -- __le32 rsv0; -- __le32 rsv1; --}; -- - u32 airoha_rr(void __iomem *base, u32 offset) - { - return readl(base + offset); ---- /dev/null -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -0,0 +1,670 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#ifndef AIROHA_REGS_H -+#define AIROHA_REGS_H -+ -+#include -+ -+/* FE */ -+#define PSE_BASE 0x0100 -+#define CSR_IFC_BASE 0x0200 -+#define CDM1_BASE 0x0400 -+#define GDM1_BASE 0x0500 -+#define PPE1_BASE 0x0c00 -+ -+#define CDM2_BASE 0x1400 -+#define GDM2_BASE 0x1500 -+ -+#define GDM3_BASE 0x1100 -+#define GDM4_BASE 0x2500 -+ -+#define GDM_BASE(_n) \ -+ ((_n) == 4 ? GDM4_BASE : \ -+ (_n) == 3 ? GDM3_BASE : \ -+ (_n) == 2 ? GDM2_BASE : GDM1_BASE) -+ -+#define REG_FE_DMA_GLO_CFG 0x0000 -+#define FE_DMA_GLO_L2_SPACE_MASK GENMASK(7, 4) -+#define FE_DMA_GLO_PG_SZ_MASK BIT(3) -+ -+#define REG_FE_RST_GLO_CFG 0x0004 -+#define FE_RST_GDM4_MBI_ARB_MASK BIT(3) -+#define FE_RST_GDM3_MBI_ARB_MASK BIT(2) -+#define FE_RST_CORE_MASK BIT(0) -+ -+#define REG_FE_WAN_MAC_H 0x0030 -+#define REG_FE_LAN_MAC_H 0x0040 -+ -+#define REG_FE_MAC_LMIN(_n) ((_n) + 0x04) -+#define REG_FE_MAC_LMAX(_n) ((_n) + 0x08) -+ -+#define REG_FE_CDM1_OQ_MAP0 0x0050 -+#define REG_FE_CDM1_OQ_MAP1 0x0054 -+#define REG_FE_CDM1_OQ_MAP2 0x0058 -+#define REG_FE_CDM1_OQ_MAP3 0x005c -+ -+#define REG_FE_PCE_CFG 0x0070 -+#define PCE_DPI_EN_MASK BIT(2) -+#define PCE_KA_EN_MASK BIT(1) -+#define PCE_MC_EN_MASK BIT(0) -+ -+#define REG_FE_PSE_QUEUE_CFG_WR 0x0080 -+#define PSE_CFG_PORT_ID_MASK GENMASK(27, 24) -+#define PSE_CFG_QUEUE_ID_MASK GENMASK(20, 16) -+#define PSE_CFG_WR_EN_MASK BIT(8) -+#define PSE_CFG_OQRSV_SEL_MASK BIT(0) -+ -+#define REG_FE_PSE_QUEUE_CFG_VAL 0x0084 -+#define PSE_CFG_OQ_RSV_MASK GENMASK(13, 0) -+ -+#define PSE_FQ_CFG 0x008c -+#define PSE_FQ_LIMIT_MASK GENMASK(14, 0) -+ -+#define REG_FE_PSE_BUF_SET 0x0090 -+#define PSE_SHARE_USED_LTHD_MASK GENMASK(31, 16) -+#define PSE_ALLRSV_MASK GENMASK(14, 0) -+ -+#define REG_PSE_SHARE_USED_THD 0x0094 -+#define PSE_SHARE_USED_MTHD_MASK GENMASK(31, 16) -+#define PSE_SHARE_USED_HTHD_MASK GENMASK(15, 0) -+ -+#define REG_GDM_MISC_CFG 0x0148 -+#define GDM2_RDM_ACK_WAIT_PREF_MASK BIT(9) -+#define GDM2_CHN_VLD_MODE_MASK BIT(5) -+ -+#define REG_FE_CSR_IFC_CFG CSR_IFC_BASE -+#define FE_IFC_EN_MASK BIT(0) -+ -+#define REG_FE_VIP_PORT_EN 0x01f0 -+#define REG_FE_IFC_PORT_EN 0x01f4 -+ -+#define REG_PSE_IQ_REV1 (PSE_BASE + 0x08) -+#define PSE_IQ_RES1_P2_MASK GENMASK(23, 16) -+ -+#define REG_PSE_IQ_REV2 (PSE_BASE + 0x0c) -+#define PSE_IQ_RES2_P5_MASK GENMASK(15, 8) -+#define PSE_IQ_RES2_P4_MASK GENMASK(7, 0) -+ -+#define REG_FE_VIP_EN(_n) (0x0300 + ((_n) << 3)) -+#define PATN_FCPU_EN_MASK BIT(7) -+#define PATN_SWP_EN_MASK BIT(6) -+#define PATN_DP_EN_MASK BIT(5) -+#define PATN_SP_EN_MASK BIT(4) -+#define PATN_TYPE_MASK GENMASK(3, 1) -+#define PATN_EN_MASK BIT(0) -+ -+#define REG_FE_VIP_PATN(_n) (0x0304 + ((_n) << 3)) -+#define PATN_DP_MASK GENMASK(31, 16) -+#define PATN_SP_MASK GENMASK(15, 0) -+ -+#define REG_CDM1_VLAN_CTRL CDM1_BASE -+#define CDM1_VLAN_MASK GENMASK(31, 16) -+ -+#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) -+#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) -+ -+#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) -+#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ -+ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -+ -+#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) -+#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) -+#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) -+ -+#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) -+#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ -+ GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -+ -+#define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) -+#define GDM_DROP_CRC_ERR BIT(23) -+#define GDM_IP4_CKSUM BIT(22) -+#define GDM_TCP_CKSUM BIT(21) -+#define GDM_UDP_CKSUM BIT(20) -+#define GDM_UCFQ_MASK GENMASK(15, 12) -+#define GDM_BCFQ_MASK GENMASK(11, 8) -+#define GDM_MCFQ_MASK GENMASK(7, 4) -+#define GDM_OCFQ_MASK GENMASK(3, 0) -+ -+#define REG_GDM_INGRESS_CFG(_n) (GDM_BASE(_n) + 0x10) -+#define GDM_INGRESS_FC_EN_MASK BIT(1) -+#define GDM_STAG_EN_MASK BIT(0) -+ -+#define REG_GDM_LEN_CFG(_n) (GDM_BASE(_n) + 0x14) -+#define GDM_SHORT_LEN_MASK GENMASK(13, 0) -+#define GDM_LONG_LEN_MASK GENMASK(29, 16) -+ -+#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) -+#define FE_CPORT_PAD BIT(26) -+#define FE_CPORT_PORT_XFC_MASK BIT(25) -+#define FE_CPORT_QUEUE_XFC_MASK BIT(24) -+ -+#define REG_FE_GDM_MIB_CLEAR(_n) (GDM_BASE(_n) + 0xf0) -+#define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) -+#define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) -+ -+#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) -+#define FE_STRICT_RFC2819_MODE_MASK BIT(31) -+#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) -+#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) -+#define FE_TX_MIB_ID_MASK GENMASK(15, 8) -+#define FE_RX_MIB_ID_MASK GENMASK(7, 0) -+ -+#define REG_FE_GDM_TX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x104) -+#define REG_FE_GDM_TX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x10c) -+#define REG_FE_GDM_TX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x110) -+#define REG_FE_GDM_TX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x114) -+#define REG_FE_GDM_TX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x118) -+#define REG_FE_GDM_TX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x11c) -+#define REG_FE_GDM_TX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x120) -+#define REG_FE_GDM_TX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x124) -+#define REG_FE_GDM_TX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x128) -+#define REG_FE_GDM_TX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x12c) -+#define REG_FE_GDM_TX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x130) -+#define REG_FE_GDM_TX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x134) -+#define REG_FE_GDM_TX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x138) -+#define REG_FE_GDM_TX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x13c) -+#define REG_FE_GDM_TX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x140) -+ -+#define REG_FE_GDM_RX_OK_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x148) -+#define REG_FE_GDM_RX_FC_DROP_CNT(_n) (GDM_BASE(_n) + 0x14c) -+#define REG_FE_GDM_RX_RC_DROP_CNT(_n) (GDM_BASE(_n) + 0x150) -+#define REG_FE_GDM_RX_OVERFLOW_DROP_CNT(_n) (GDM_BASE(_n) + 0x154) -+#define REG_FE_GDM_RX_ERROR_DROP_CNT(_n) (GDM_BASE(_n) + 0x158) -+#define REG_FE_GDM_RX_OK_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x15c) -+#define REG_FE_GDM_RX_ETH_PKT_CNT_L(_n) (GDM_BASE(_n) + 0x160) -+#define REG_FE_GDM_RX_ETH_BYTE_CNT_L(_n) (GDM_BASE(_n) + 0x164) -+#define REG_FE_GDM_RX_ETH_DROP_CNT(_n) (GDM_BASE(_n) + 0x168) -+#define REG_FE_GDM_RX_ETH_BC_CNT(_n) (GDM_BASE(_n) + 0x16c) -+#define REG_FE_GDM_RX_ETH_MC_CNT(_n) (GDM_BASE(_n) + 0x170) -+#define REG_FE_GDM_RX_ETH_CRC_ERR_CNT(_n) (GDM_BASE(_n) + 0x174) -+#define REG_FE_GDM_RX_ETH_FRAG_CNT(_n) (GDM_BASE(_n) + 0x178) -+#define REG_FE_GDM_RX_ETH_JABBER_CNT(_n) (GDM_BASE(_n) + 0x17c) -+#define REG_FE_GDM_RX_ETH_RUNT_CNT(_n) (GDM_BASE(_n) + 0x180) -+#define REG_FE_GDM_RX_ETH_LONG_CNT(_n) (GDM_BASE(_n) + 0x184) -+#define REG_FE_GDM_RX_ETH_E64_CNT_L(_n) (GDM_BASE(_n) + 0x188) -+#define REG_FE_GDM_RX_ETH_L64_CNT_L(_n) (GDM_BASE(_n) + 0x18c) -+#define REG_FE_GDM_RX_ETH_L127_CNT_L(_n) (GDM_BASE(_n) + 0x190) -+#define REG_FE_GDM_RX_ETH_L255_CNT_L(_n) (GDM_BASE(_n) + 0x194) -+#define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) -+#define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) -+ -+#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) -+#define PPE1_SRAM_TABLE_EN_MASK BIT(0) -+#define PPE1_SRAM_HASH1_EN_MASK BIT(8) -+#define PPE1_DRAM_TABLE_EN_MASK BIT(16) -+#define PPE1_DRAM_HASH1_EN_MASK BIT(24) -+ -+#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) -+#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) -+#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) -+#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) -+ -+#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) -+#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) -+#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) -+#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) -+#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) -+#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) -+#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) -+#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) -+#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) -+#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) -+#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) -+#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) -+#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) -+#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) -+#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) -+#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) -+ -+#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) -+#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) -+#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) -+ -+#define REG_GDM3_FWD_CFG GDM3_BASE -+#define GDM3_PAD_EN_MASK BIT(28) -+ -+#define REG_GDM4_FWD_CFG GDM4_BASE -+#define GDM4_PAD_EN_MASK BIT(28) -+#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) -+ -+#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) -+#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) -+#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) -+#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) -+ -+#define REG_IP_FRAG_FP 0x2010 -+#define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) -+#define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) -+#define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) -+#define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) -+ -+#define REG_MC_VLAN_EN 0x2100 -+#define MC_VLAN_EN_MASK BIT(0) -+ -+#define REG_MC_VLAN_CFG 0x2104 -+#define MC_VLAN_CFG_CMD_DONE_MASK BIT(31) -+#define MC_VLAN_CFG_TABLE_ID_MASK GENMASK(21, 16) -+#define MC_VLAN_CFG_PORT_ID_MASK GENMASK(11, 8) -+#define MC_VLAN_CFG_TABLE_SEL_MASK BIT(4) -+#define MC_VLAN_CFG_RW_MASK BIT(0) -+ -+#define REG_MC_VLAN_DATA 0x2108 -+ -+#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 -+ -+/* QDMA */ -+#define REG_QDMA_GLOBAL_CFG 0x0004 -+#define GLOBAL_CFG_RX_2B_OFFSET_MASK BIT(31) -+#define GLOBAL_CFG_DMA_PREFERENCE_MASK GENMASK(30, 29) -+#define GLOBAL_CFG_CPU_TXR_RR_MASK BIT(28) -+#define GLOBAL_CFG_DSCP_BYTE_SWAP_MASK BIT(27) -+#define GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK BIT(26) -+#define GLOBAL_CFG_MULTICAST_MODIFY_FP_MASK BIT(25) -+#define GLOBAL_CFG_OAM_MODIFY_MASK BIT(24) -+#define GLOBAL_CFG_RESET_MASK BIT(23) -+#define GLOBAL_CFG_RESET_DONE_MASK BIT(22) -+#define GLOBAL_CFG_MULTICAST_EN_MASK BIT(21) -+#define GLOBAL_CFG_IRQ1_EN_MASK BIT(20) -+#define GLOBAL_CFG_IRQ0_EN_MASK BIT(19) -+#define GLOBAL_CFG_LOOPCNT_EN_MASK BIT(18) -+#define GLOBAL_CFG_RD_BYPASS_WR_MASK BIT(17) -+#define GLOBAL_CFG_QDMA_LOOPBACK_MASK BIT(16) -+#define GLOBAL_CFG_LPBK_RXQ_SEL_MASK GENMASK(13, 8) -+#define GLOBAL_CFG_CHECK_DONE_MASK BIT(7) -+#define GLOBAL_CFG_TX_WB_DONE_MASK BIT(6) -+#define GLOBAL_CFG_MAX_ISSUE_NUM_MASK GENMASK(5, 4) -+#define GLOBAL_CFG_RX_DMA_BUSY_MASK BIT(3) -+#define GLOBAL_CFG_RX_DMA_EN_MASK BIT(2) -+#define GLOBAL_CFG_TX_DMA_BUSY_MASK BIT(1) -+#define GLOBAL_CFG_TX_DMA_EN_MASK BIT(0) -+ -+#define REG_FWD_DSCP_BASE 0x0010 -+#define REG_FWD_BUF_BASE 0x0014 -+ -+#define REG_HW_FWD_DSCP_CFG 0x0018 -+#define HW_FWD_DSCP_PAYLOAD_SIZE_MASK GENMASK(29, 28) -+#define HW_FWD_DSCP_SCATTER_LEN_MASK GENMASK(17, 16) -+#define HW_FWD_DSCP_MIN_SCATTER_LEN_MASK GENMASK(15, 0) -+ -+#define REG_INT_STATUS(_n) \ -+ (((_n) == 4) ? 0x0730 : \ -+ ((_n) == 3) ? 0x0724 : \ -+ ((_n) == 2) ? 0x0720 : \ -+ ((_n) == 1) ? 0x0024 : 0x0020) -+ -+#define REG_INT_ENABLE(_n) \ -+ (((_n) == 4) ? 0x0750 : \ -+ ((_n) == 3) ? 0x0744 : \ -+ ((_n) == 2) ? 0x0740 : \ -+ ((_n) == 1) ? 0x002c : 0x0028) -+ -+/* QDMA_CSR_INT_ENABLE1 */ -+#define RX15_COHERENT_INT_MASK BIT(31) -+#define RX14_COHERENT_INT_MASK BIT(30) -+#define RX13_COHERENT_INT_MASK BIT(29) -+#define RX12_COHERENT_INT_MASK BIT(28) -+#define RX11_COHERENT_INT_MASK BIT(27) -+#define RX10_COHERENT_INT_MASK BIT(26) -+#define RX9_COHERENT_INT_MASK BIT(25) -+#define RX8_COHERENT_INT_MASK BIT(24) -+#define RX7_COHERENT_INT_MASK BIT(23) -+#define RX6_COHERENT_INT_MASK BIT(22) -+#define RX5_COHERENT_INT_MASK BIT(21) -+#define RX4_COHERENT_INT_MASK BIT(20) -+#define RX3_COHERENT_INT_MASK BIT(19) -+#define RX2_COHERENT_INT_MASK BIT(18) -+#define RX1_COHERENT_INT_MASK BIT(17) -+#define RX0_COHERENT_INT_MASK BIT(16) -+#define TX7_COHERENT_INT_MASK BIT(15) -+#define TX6_COHERENT_INT_MASK BIT(14) -+#define TX5_COHERENT_INT_MASK BIT(13) -+#define TX4_COHERENT_INT_MASK BIT(12) -+#define TX3_COHERENT_INT_MASK BIT(11) -+#define TX2_COHERENT_INT_MASK BIT(10) -+#define TX1_COHERENT_INT_MASK BIT(9) -+#define TX0_COHERENT_INT_MASK BIT(8) -+#define CNT_OVER_FLOW_INT_MASK BIT(7) -+#define IRQ1_FULL_INT_MASK BIT(5) -+#define IRQ1_INT_MASK BIT(4) -+#define HWFWD_DSCP_LOW_INT_MASK BIT(3) -+#define HWFWD_DSCP_EMPTY_INT_MASK BIT(2) -+#define IRQ0_FULL_INT_MASK BIT(1) -+#define IRQ0_INT_MASK BIT(0) -+ -+#define TX_DONE_INT_MASK(_n) \ -+ ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ -+ : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -+ -+#define INT_TX_MASK \ -+ (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ -+ IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -+ -+#define INT_IDX0_MASK \ -+ (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ -+ TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ -+ TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ -+ TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ -+ RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ -+ RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ -+ RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ -+ RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ -+ RX15_COHERENT_INT_MASK | INT_TX_MASK) -+ -+/* QDMA_CSR_INT_ENABLE2 */ -+#define RX15_NO_CPU_DSCP_INT_MASK BIT(31) -+#define RX14_NO_CPU_DSCP_INT_MASK BIT(30) -+#define RX13_NO_CPU_DSCP_INT_MASK BIT(29) -+#define RX12_NO_CPU_DSCP_INT_MASK BIT(28) -+#define RX11_NO_CPU_DSCP_INT_MASK BIT(27) -+#define RX10_NO_CPU_DSCP_INT_MASK BIT(26) -+#define RX9_NO_CPU_DSCP_INT_MASK BIT(25) -+#define RX8_NO_CPU_DSCP_INT_MASK BIT(24) -+#define RX7_NO_CPU_DSCP_INT_MASK BIT(23) -+#define RX6_NO_CPU_DSCP_INT_MASK BIT(22) -+#define RX5_NO_CPU_DSCP_INT_MASK BIT(21) -+#define RX4_NO_CPU_DSCP_INT_MASK BIT(20) -+#define RX3_NO_CPU_DSCP_INT_MASK BIT(19) -+#define RX2_NO_CPU_DSCP_INT_MASK BIT(18) -+#define RX1_NO_CPU_DSCP_INT_MASK BIT(17) -+#define RX0_NO_CPU_DSCP_INT_MASK BIT(16) -+#define RX15_DONE_INT_MASK BIT(15) -+#define RX14_DONE_INT_MASK BIT(14) -+#define RX13_DONE_INT_MASK BIT(13) -+#define RX12_DONE_INT_MASK BIT(12) -+#define RX11_DONE_INT_MASK BIT(11) -+#define RX10_DONE_INT_MASK BIT(10) -+#define RX9_DONE_INT_MASK BIT(9) -+#define RX8_DONE_INT_MASK BIT(8) -+#define RX7_DONE_INT_MASK BIT(7) -+#define RX6_DONE_INT_MASK BIT(6) -+#define RX5_DONE_INT_MASK BIT(5) -+#define RX4_DONE_INT_MASK BIT(4) -+#define RX3_DONE_INT_MASK BIT(3) -+#define RX2_DONE_INT_MASK BIT(2) -+#define RX1_DONE_INT_MASK BIT(1) -+#define RX0_DONE_INT_MASK BIT(0) -+ -+#define RX_DONE_INT_MASK \ -+ (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ -+ RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ -+ RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ -+ RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ -+ RX15_DONE_INT_MASK) -+#define INT_IDX1_MASK \ -+ (RX_DONE_INT_MASK | \ -+ RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ -+ RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ -+ RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ -+ RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ -+ RX15_NO_CPU_DSCP_INT_MASK) -+ -+/* QDMA_CSR_INT_ENABLE5 */ -+#define TX31_COHERENT_INT_MASK BIT(31) -+#define TX30_COHERENT_INT_MASK BIT(30) -+#define TX29_COHERENT_INT_MASK BIT(29) -+#define TX28_COHERENT_INT_MASK BIT(28) -+#define TX27_COHERENT_INT_MASK BIT(27) -+#define TX26_COHERENT_INT_MASK BIT(26) -+#define TX25_COHERENT_INT_MASK BIT(25) -+#define TX24_COHERENT_INT_MASK BIT(24) -+#define TX23_COHERENT_INT_MASK BIT(23) -+#define TX22_COHERENT_INT_MASK BIT(22) -+#define TX21_COHERENT_INT_MASK BIT(21) -+#define TX20_COHERENT_INT_MASK BIT(20) -+#define TX19_COHERENT_INT_MASK BIT(19) -+#define TX18_COHERENT_INT_MASK BIT(18) -+#define TX17_COHERENT_INT_MASK BIT(17) -+#define TX16_COHERENT_INT_MASK BIT(16) -+#define TX15_COHERENT_INT_MASK BIT(15) -+#define TX14_COHERENT_INT_MASK BIT(14) -+#define TX13_COHERENT_INT_MASK BIT(13) -+#define TX12_COHERENT_INT_MASK BIT(12) -+#define TX11_COHERENT_INT_MASK BIT(11) -+#define TX10_COHERENT_INT_MASK BIT(10) -+#define TX9_COHERENT_INT_MASK BIT(9) -+#define TX8_COHERENT_INT_MASK BIT(8) -+ -+#define INT_IDX4_MASK \ -+ (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ -+ TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ -+ TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ -+ TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ -+ TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ -+ TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ -+ TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ -+ TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ -+ TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ -+ TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ -+ TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ -+ TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) -+ -+#define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) -+ -+#define REG_TX_IRQ_CFG(_n) ((_n) ? 0x004c : 0x0054) -+#define TX_IRQ_THR_MASK GENMASK(27, 16) -+#define TX_IRQ_DEPTH_MASK GENMASK(11, 0) -+ -+#define REG_IRQ_CLEAR_LEN(_n) ((_n) ? 0x0064 : 0x0058) -+#define IRQ_CLEAR_LEN_MASK GENMASK(7, 0) -+ -+#define REG_IRQ_STATUS(_n) ((_n) ? 0x0068 : 0x005c) -+#define IRQ_ENTRY_LEN_MASK GENMASK(27, 16) -+#define IRQ_HEAD_IDX_MASK GENMASK(11, 0) -+ -+#define REG_TX_RING_BASE(_n) \ -+ (((_n) < 8) ? 0x0100 + ((_n) << 5) : 0x0b00 + (((_n) - 8) << 5)) -+ -+#define REG_TX_RING_BLOCKING(_n) \ -+ (((_n) < 8) ? 0x0104 + ((_n) << 5) : 0x0b04 + (((_n) - 8) << 5)) -+ -+#define TX_RING_IRQ_BLOCKING_MAP_MASK BIT(6) -+#define TX_RING_IRQ_BLOCKING_CFG_MASK BIT(4) -+#define TX_RING_IRQ_BLOCKING_TX_DROP_EN_MASK BIT(2) -+#define TX_RING_IRQ_BLOCKING_MAX_TH_TXRING_EN_MASK BIT(1) -+#define TX_RING_IRQ_BLOCKING_MIN_TH_TXRING_EN_MASK BIT(0) -+ -+#define REG_TX_CPU_IDX(_n) \ -+ (((_n) < 8) ? 0x0108 + ((_n) << 5) : 0x0b08 + (((_n) - 8) << 5)) -+ -+#define TX_RING_CPU_IDX_MASK GENMASK(15, 0) -+ -+#define REG_TX_DMA_IDX(_n) \ -+ (((_n) < 8) ? 0x010c + ((_n) << 5) : 0x0b0c + (((_n) - 8) << 5)) -+ -+#define TX_RING_DMA_IDX_MASK GENMASK(15, 0) -+ -+#define IRQ_RING_IDX_MASK GENMASK(20, 16) -+#define IRQ_DESC_IDX_MASK GENMASK(15, 0) -+ -+#define REG_RX_RING_BASE(_n) \ -+ (((_n) < 16) ? 0x0200 + ((_n) << 5) : 0x0e00 + (((_n) - 16) << 5)) -+ -+#define REG_RX_RING_SIZE(_n) \ -+ (((_n) < 16) ? 0x0204 + ((_n) << 5) : 0x0e04 + (((_n) - 16) << 5)) -+ -+#define RX_RING_THR_MASK GENMASK(31, 16) -+#define RX_RING_SIZE_MASK GENMASK(15, 0) -+ -+#define REG_RX_CPU_IDX(_n) \ -+ (((_n) < 16) ? 0x0208 + ((_n) << 5) : 0x0e08 + (((_n) - 16) << 5)) -+ -+#define RX_RING_CPU_IDX_MASK GENMASK(15, 0) -+ -+#define REG_RX_DMA_IDX(_n) \ -+ (((_n) < 16) ? 0x020c + ((_n) << 5) : 0x0e0c + (((_n) - 16) << 5)) -+ -+#define REG_RX_DELAY_INT_IDX(_n) \ -+ (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) -+ -+#define RX_DELAY_INT_MASK GENMASK(15, 0) -+ -+#define RX_RING_DMA_IDX_MASK GENMASK(15, 0) -+ -+#define REG_INGRESS_TRTCM_CFG 0x0070 -+#define INGRESS_TRTCM_EN_MASK BIT(31) -+#define INGRESS_TRTCM_MODE_MASK BIT(30) -+#define INGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define INGRESS_FAST_TICK_MASK GENMASK(15, 0) -+ -+#define REG_QUEUE_CLOSE_CFG(_n) (0x00a0 + ((_n) & 0xfc)) -+#define TXQ_DISABLE_CHAN_QUEUE_MASK(_n, _m) BIT((_m) + (((_n) & 0x3) << 3)) -+ -+#define REG_TXQ_DIS_CFG_BASE(_n) ((_n) ? 0x20a0 : 0x00a0) -+#define REG_TXQ_DIS_CFG(_n, _m) (REG_TXQ_DIS_CFG_BASE((_n)) + (_m) << 2) -+ -+#define REG_CNTR_CFG(_n) (0x0400 + ((_n) << 3)) -+#define CNTR_EN_MASK BIT(31) -+#define CNTR_ALL_CHAN_EN_MASK BIT(30) -+#define CNTR_ALL_QUEUE_EN_MASK BIT(29) -+#define CNTR_ALL_DSCP_RING_EN_MASK BIT(28) -+#define CNTR_SRC_MASK GENMASK(27, 24) -+#define CNTR_DSCP_RING_MASK GENMASK(20, 16) -+#define CNTR_CHAN_MASK GENMASK(7, 3) -+#define CNTR_QUEUE_MASK GENMASK(2, 0) -+ -+#define REG_CNTR_VAL(_n) (0x0404 + ((_n) << 3)) -+ -+#define REG_LMGR_INIT_CFG 0x1000 -+#define LMGR_INIT_START BIT(31) -+#define LMGR_SRAM_MODE_MASK BIT(30) -+#define HW_FWD_PKTSIZE_OVERHEAD_MASK GENMASK(27, 20) -+#define HW_FWD_DESC_NUM_MASK GENMASK(16, 0) -+ -+#define REG_FWD_DSCP_LOW_THR 0x1004 -+#define FWD_DSCP_LOW_THR_MASK GENMASK(17, 0) -+ -+#define REG_EGRESS_RATE_METER_CFG 0x100c -+#define EGRESS_RATE_METER_EN_MASK BIT(31) -+#define EGRESS_RATE_METER_EQ_RATE_EN_MASK BIT(17) -+#define EGRESS_RATE_METER_WINDOW_SZ_MASK GENMASK(16, 12) -+#define EGRESS_RATE_METER_TIMESLICE_MASK GENMASK(10, 0) -+ -+#define REG_EGRESS_TRTCM_CFG 0x1010 -+#define EGRESS_TRTCM_EN_MASK BIT(31) -+#define EGRESS_TRTCM_MODE_MASK BIT(30) -+#define EGRESS_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define EGRESS_FAST_TICK_MASK GENMASK(15, 0) -+ -+#define TRTCM_PARAM_RW_MASK BIT(31) -+#define TRTCM_PARAM_RW_DONE_MASK BIT(30) -+#define TRTCM_PARAM_TYPE_MASK GENMASK(29, 28) -+#define TRTCM_METER_GROUP_MASK GENMASK(27, 26) -+#define TRTCM_PARAM_INDEX_MASK GENMASK(23, 17) -+#define TRTCM_PARAM_RATE_TYPE_MASK BIT(16) -+ -+#define REG_TRTCM_CFG_PARAM(_n) ((_n) + 0x4) -+#define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) -+#define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) -+ -+#define REG_TXWRR_MODE_CFG 0x1020 -+#define TWRR_WEIGHT_SCALE_MASK BIT(31) -+#define TWRR_WEIGHT_BASE_MASK BIT(3) -+ -+#define REG_TXWRR_WEIGHT_CFG 0x1024 -+#define TWRR_RW_CMD_MASK BIT(31) -+#define TWRR_RW_CMD_DONE BIT(30) -+#define TWRR_CHAN_IDX_MASK GENMASK(23, 19) -+#define TWRR_QUEUE_IDX_MASK GENMASK(18, 16) -+#define TWRR_VALUE_MASK GENMASK(15, 0) -+ -+#define REG_PSE_BUF_USAGE_CFG 0x1028 -+#define PSE_BUF_ESTIMATE_EN_MASK BIT(29) -+ -+#define REG_CHAN_QOS_MODE(_n) (0x1040 + ((_n) << 2)) -+#define CHAN_QOS_MODE_MASK(_n) GENMASK(2 + ((_n) << 2), (_n) << 2) -+ -+#define REG_GLB_TRTCM_CFG 0x1080 -+#define GLB_TRTCM_EN_MASK BIT(31) -+#define GLB_TRTCM_MODE_MASK BIT(30) -+#define GLB_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define GLB_FAST_TICK_MASK GENMASK(15, 0) -+ -+#define REG_TXQ_CNGST_CFG 0x10a0 -+#define TXQ_CNGST_DROP_EN BIT(31) -+#define TXQ_CNGST_DEI_DROP_EN BIT(30) -+ -+#define REG_SLA_TRTCM_CFG 0x1150 -+#define SLA_TRTCM_EN_MASK BIT(31) -+#define SLA_TRTCM_MODE_MASK BIT(30) -+#define SLA_SLOW_TICK_RATIO_MASK GENMASK(29, 16) -+#define SLA_FAST_TICK_MASK GENMASK(15, 0) -+ -+/* CTRL */ -+#define QDMA_DESC_DONE_MASK BIT(31) -+#define QDMA_DESC_DROP_MASK BIT(30) /* tx: drop - rx: overflow */ -+#define QDMA_DESC_MORE_MASK BIT(29) /* more SG elements */ -+#define QDMA_DESC_DEI_MASK BIT(25) -+#define QDMA_DESC_NO_DROP_MASK BIT(24) -+#define QDMA_DESC_LEN_MASK GENMASK(15, 0) -+/* DATA */ -+#define QDMA_DESC_NEXT_ID_MASK GENMASK(15, 0) -+/* TX MSG0 */ -+#define QDMA_ETH_TXMSG_MIC_IDX_MASK BIT(30) -+#define QDMA_ETH_TXMSG_SP_TAG_MASK GENMASK(29, 14) -+#define QDMA_ETH_TXMSG_ICO_MASK BIT(13) -+#define QDMA_ETH_TXMSG_UCO_MASK BIT(12) -+#define QDMA_ETH_TXMSG_TCO_MASK BIT(11) -+#define QDMA_ETH_TXMSG_TSO_MASK BIT(10) -+#define QDMA_ETH_TXMSG_FAST_MASK BIT(9) -+#define QDMA_ETH_TXMSG_OAM_MASK BIT(8) -+#define QDMA_ETH_TXMSG_CHAN_MASK GENMASK(7, 3) -+#define QDMA_ETH_TXMSG_QUEUE_MASK GENMASK(2, 0) -+/* TX MSG1 */ -+#define QDMA_ETH_TXMSG_NO_DROP BIT(31) -+#define QDMA_ETH_TXMSG_METER_MASK GENMASK(30, 24) /* 0x7f no meters */ -+#define QDMA_ETH_TXMSG_FPORT_MASK GENMASK(23, 20) -+#define QDMA_ETH_TXMSG_NBOQ_MASK GENMASK(19, 15) -+#define QDMA_ETH_TXMSG_HWF_MASK BIT(14) -+#define QDMA_ETH_TXMSG_HOP_MASK BIT(13) -+#define QDMA_ETH_TXMSG_PTP_MASK BIT(12) -+#define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ -+#define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ -+ -+/* RX MSG1 */ -+#define QDMA_ETH_RXMSG_DEI_MASK BIT(31) -+#define QDMA_ETH_RXMSG_IP6_MASK BIT(30) -+#define QDMA_ETH_RXMSG_IP4_MASK BIT(29) -+#define QDMA_ETH_RXMSG_IP4F_MASK BIT(28) -+#define QDMA_ETH_RXMSG_L4_VALID_MASK BIT(27) -+#define QDMA_ETH_RXMSG_L4F_MASK BIT(26) -+#define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) -+#define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) -+#define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) -+ -+struct airoha_qdma_desc { -+ __le32 rsv; -+ __le32 ctrl; -+ __le32 addr; -+ __le32 data; -+ __le32 msg0; -+ __le32 msg1; -+ __le32 msg2; -+ __le32 msg3; -+}; -+ -+/* CTRL0 */ -+#define QDMA_FWD_DESC_CTX_MASK BIT(31) -+#define QDMA_FWD_DESC_RING_MASK GENMASK(30, 28) -+#define QDMA_FWD_DESC_IDX_MASK GENMASK(27, 16) -+#define QDMA_FWD_DESC_LEN_MASK GENMASK(15, 0) -+/* CTRL1 */ -+#define QDMA_FWD_DESC_FIRST_IDX_MASK GENMASK(15, 0) -+/* CTRL2 */ -+#define QDMA_FWD_DESC_MORE_PKT_NUM_MASK GENMASK(2, 0) -+ -+struct airoha_qdma_fwd_desc { -+ __le32 addr; -+ __le32 ctrl0; -+ __le32 ctrl1; -+ __le32 ctrl2; -+ __le32 msg0; -+ __le32 msg1; -+ __le32 rsv0; -+ __le32 rsv1; -+}; -+ -+#endif /* AIROHA_REGS_H */ diff --git a/target/linux/airoha/patches-6.12/048-05-v6.15-net-airoha-Move-DSA-tag-in-DMA-descriptor.patch b/target/linux/airoha/patches-6.12/048-05-v6.15-net-airoha-Move-DSA-tag-in-DMA-descriptor.patch deleted file mode 100644 index f9d6373fc95..00000000000 --- a/target/linux/airoha/patches-6.12/048-05-v6.15-net-airoha-Move-DSA-tag-in-DMA-descriptor.patch +++ /dev/null @@ -1,287 +0,0 @@ -From af3cf757d5c99011b9b94ea8d78aeaccc0153fdc Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:13 +0100 -Subject: [PATCH 05/15] net: airoha: Move DSA tag in DMA descriptor - -Packet Processor Engine (PPE) module reads DSA tags from the DMA descriptor -and requires untagged DSA packets to properly parse them. Move DSA tag -in the DMA descriptor on TX side and read DSA tag from DMA descriptor -on RX side. In order to avoid skb reallocation, store tag in skb_dst on -RX side. -This is a preliminary patch to enable netfilter flowtable hw offloading -on EN7581 SoC. - -Tested-by: Sayantan Nandy -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 125 ++++++++++++++++++++-- - drivers/net/ethernet/airoha/airoha_eth.h | 7 ++ - drivers/net/ethernet/airoha/airoha_regs.h | 2 + - 3 files changed, 128 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -656,6 +657,7 @@ static int airoha_qdma_rx_process(struct - struct airoha_qdma_desc *desc = &q->desc[q->tail]; - dma_addr_t dma_addr = le32_to_cpu(desc->addr); - u32 desc_ctrl = le32_to_cpu(desc->ctrl); -+ struct airoha_gdm_port *port; - struct sk_buff *skb; - int len, p; - -@@ -683,6 +685,7 @@ static int airoha_qdma_rx_process(struct - continue; - } - -+ port = eth->ports[p]; - skb = napi_build_skb(e->buf, q->buf_size); - if (!skb) { - page_pool_put_full_page(q->page_pool, -@@ -694,10 +697,26 @@ static int airoha_qdma_rx_process(struct - skb_reserve(skb, 2); - __skb_put(skb, len); - skb_mark_for_recycle(skb); -- skb->dev = eth->ports[p]->dev; -+ skb->dev = port->dev; - skb->protocol = eth_type_trans(skb, skb->dev); - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb_record_rx_queue(skb, qid); -+ -+ if (netdev_uses_dsa(port->dev)) { -+ /* PPE module requires untagged packets to work -+ * properly and it provides DSA port index via the -+ * DMA descriptor. Report DSA tag to the DSA stack -+ * via skb dst info. -+ */ -+ u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG, -+ le32_to_cpu(desc->msg0)); -+ -+ if (sptag < ARRAY_SIZE(port->dsa_meta) && -+ port->dsa_meta[sptag]) -+ skb_dst_set_noref(skb, -+ &port->dsa_meta[sptag]->dst); -+ } -+ - napi_gro_receive(&q->napi, skb); - - done++; -@@ -1657,25 +1676,76 @@ static u16 airoha_dev_select_queue(struc - return queue < dev->num_tx_queues ? queue : 0; - } - -+static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev) -+{ -+#if IS_ENABLED(CONFIG_NET_DSA) -+ struct ethhdr *ehdr; -+ struct dsa_port *dp; -+ u8 xmit_tpid; -+ u16 tag; -+ -+ if (!netdev_uses_dsa(dev)) -+ return 0; -+ -+ dp = dev->dsa_ptr; -+ if (IS_ERR(dp)) -+ return 0; -+ -+ if (dp->tag_ops->proto != DSA_TAG_PROTO_MTK) -+ return 0; -+ -+ if (skb_cow_head(skb, 0)) -+ return 0; -+ -+ ehdr = (struct ethhdr *)skb->data; -+ tag = be16_to_cpu(ehdr->h_proto); -+ xmit_tpid = tag >> 8; -+ -+ switch (xmit_tpid) { -+ case MTK_HDR_XMIT_TAGGED_TPID_8100: -+ ehdr->h_proto = cpu_to_be16(ETH_P_8021Q); -+ tag &= ~(MTK_HDR_XMIT_TAGGED_TPID_8100 << 8); -+ break; -+ case MTK_HDR_XMIT_TAGGED_TPID_88A8: -+ ehdr->h_proto = cpu_to_be16(ETH_P_8021AD); -+ tag &= ~(MTK_HDR_XMIT_TAGGED_TPID_88A8 << 8); -+ break; -+ default: -+ /* PPE module requires untagged DSA packets to work properly, -+ * so move DSA tag to DMA descriptor. -+ */ -+ memmove(skb->data + MTK_HDR_LEN, skb->data, 2 * ETH_ALEN); -+ __skb_pull(skb, MTK_HDR_LEN); -+ break; -+ } -+ -+ return tag; -+#else -+ return 0; -+#endif -+} -+ - static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, - struct net_device *dev) - { - struct airoha_gdm_port *port = netdev_priv(dev); -- u32 nr_frags = 1 + skb_shinfo(skb)->nr_frags; -- u32 msg0, msg1, len = skb_headlen(skb); - struct airoha_qdma *qdma = port->qdma; -+ u32 nr_frags, tag, msg0, msg1, len; - struct netdev_queue *txq; - struct airoha_queue *q; -- void *data = skb->data; -+ void *data; - int i, qid; - u16 index; - u8 fport; - - qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); -+ tag = airoha_get_dsa_tag(skb, dev); -+ - msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, - qid / AIROHA_NUM_QOS_QUEUES) | - FIELD_PREP(QDMA_ETH_TXMSG_QUEUE_MASK, -- qid % AIROHA_NUM_QOS_QUEUES); -+ qid % AIROHA_NUM_QOS_QUEUES) | -+ FIELD_PREP(QDMA_ETH_TXMSG_SP_TAG_MASK, tag); - if (skb->ip_summed == CHECKSUM_PARTIAL) - msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) | - FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) | -@@ -1706,6 +1776,8 @@ static netdev_tx_t airoha_dev_xmit(struc - spin_lock_bh(&q->lock); - - txq = netdev_get_tx_queue(dev, qid); -+ nr_frags = 1 + skb_shinfo(skb)->nr_frags; -+ - if (q->queued + nr_frags > q->ndesc) { - /* not enough space in the queue */ - netif_tx_stop_queue(txq); -@@ -1713,7 +1785,10 @@ static netdev_tx_t airoha_dev_xmit(struc - return NETDEV_TX_BUSY; - } - -+ len = skb_headlen(skb); -+ data = skb->data; - index = q->head; -+ - for (i = 0; i < nr_frags; i++) { - struct airoha_qdma_desc *desc = &q->desc[index]; - struct airoha_queue_entry *e = &q->entry[index]; -@@ -2244,6 +2319,37 @@ static const struct ethtool_ops airoha_e - .get_rmon_stats = airoha_ethtool_get_rmon_stats, - }; - -+static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { -+ struct metadata_dst *md_dst; -+ -+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, -+ GFP_KERNEL); -+ if (!md_dst) -+ return -ENOMEM; -+ -+ md_dst->u.port_info.port_id = i; -+ port->dsa_meta[i] = md_dst; -+ } -+ -+ return 0; -+} -+ -+static void airoha_metadata_dst_free(struct airoha_gdm_port *port) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(port->dsa_meta); i++) { -+ if (!port->dsa_meta[i]) -+ continue; -+ -+ metadata_dst_free(port->dsa_meta[i]); -+ } -+} -+ - static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) - { - const __be32 *id_ptr = of_get_property(np, "reg", NULL); -@@ -2316,6 +2422,10 @@ static int airoha_alloc_gdm_port(struct - port->id = id; - eth->ports[index] = port; - -+ err = airoha_metadata_dst_alloc(port); -+ if (err) -+ return err; -+ - return register_netdev(dev); - } - -@@ -2408,8 +2518,10 @@ error_hw_cleanup: - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; - -- if (port && port->dev->reg_state == NETREG_REGISTERED) -+ if (port && port->dev->reg_state == NETREG_REGISTERED) { - unregister_netdev(port->dev); -+ airoha_metadata_dst_free(port); -+ } - } - free_netdev(eth->napi_dev); - platform_set_drvdata(pdev, NULL); -@@ -2434,6 +2546,7 @@ static void airoha_remove(struct platfor - continue; - - unregister_netdev(port->dev); -+ airoha_metadata_dst_free(port); - } - free_netdev(eth->napi_dev); - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -15,6 +15,7 @@ - - #define AIROHA_MAX_NUM_GDM_PORTS 1 - #define AIROHA_MAX_NUM_QDMA 2 -+#define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 - #define AIROHA_MAX_NUM_XSI_RSTS 5 - #define AIROHA_MAX_MTU 2000 -@@ -43,6 +44,10 @@ - #define QDMA_METER_IDX(_n) ((_n) & 0xff) - #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) - -+#define MTK_HDR_LEN 4 -+#define MTK_HDR_XMIT_TAGGED_TPID_8100 1 -+#define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 -+ - enum { - QDMA_INT_REG_IDX0, - QDMA_INT_REG_IDX1, -@@ -231,6 +236,8 @@ struct airoha_gdm_port { - /* qos stats counters */ - u64 cpu_tx_packets; - u64 fwd_tx_packets; -+ -+ struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; - }; - - struct airoha_eth { ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -624,6 +624,8 @@ - #define QDMA_ETH_TXMSG_ACNT_G1_MASK GENMASK(10, 6) /* 0x1f do not count */ - #define QDMA_ETH_TXMSG_ACNT_G0_MASK GENMASK(5, 0) /* 0x3f do not count */ - -+/* RX MSG0 */ -+#define QDMA_ETH_RXMSG_SPTAG GENMASK(21, 14) - /* RX MSG1 */ - #define QDMA_ETH_RXMSG_DEI_MASK BIT(31) - #define QDMA_ETH_RXMSG_IP6_MASK BIT(30) diff --git a/target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch deleted file mode 100644 index 71822d69d9d..00000000000 --- a/target/linux/airoha/patches-6.12/048-06-v6.15-net-dsa-mt7530-Enable-Rx-sptag-for-EN7581-SoC.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ab667db1e6014634c6607ebdddc16c1b8394a935 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:14 +0100 -Subject: [PATCH 06/15] net: dsa: mt7530: Enable Rx sptag for EN7581 SoC - -Packet Processor Engine (PPE) module used for hw acceleration on EN7581 -mac block, in order to properly parse packets, requires DSA untagged -packets on TX side and read DSA tag from DMA descriptor on RX side. -For this reason, enable RX Special Tag (SPTAG) for EN7581 SoC. -This is a preliminary patch to enable netfilter flowtable hw offloading -on EN7581 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 5 +++++ - drivers/net/dsa/mt7530.h | 4 ++++ - 2 files changed, 9 insertions(+) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2599,6 +2599,11 @@ mt7531_setup_common(struct dsa_switch *d - /* Allow mirroring frames received on the local port (monitor port). */ - mt7530_set(priv, MT753X_AGC, LOCAL_EN); - -+ /* Enable Special Tag for rx frames */ -+ if (priv->id == ID_EN7581) -+ mt7530_write(priv, MT753X_CPORT_SPTAG_CFG, -+ CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN); -+ - /* Flush the FDB table */ - ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); - if (ret < 0) ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -615,6 +615,10 @@ enum mt7531_xtal_fsel { - #define MT7531_GPIO12_RG_RXD3_MASK GENMASK(19, 16) - #define MT7531_EXT_P_MDIO_12 (2 << 16) - -+#define MT753X_CPORT_SPTAG_CFG 0x7c10 -+#define CPORT_SW2FE_STAG_EN BIT(1) -+#define CPORT_FE2SW_STAG_EN BIT(0) -+ - /* Registers for LED GPIO control (MT7530 only) - * All registers follow this pattern: - * [ 2: 0] port 0 diff --git a/target/linux/airoha/patches-6.12/048-07-v6.15-net-airoha-Enable-support-for-multiple-net_devices.patch b/target/linux/airoha/patches-6.12/048-07-v6.15-net-airoha-Enable-support-for-multiple-net_devices.patch deleted file mode 100644 index 3441758c1fa..00000000000 --- a/target/linux/airoha/patches-6.12/048-07-v6.15-net-airoha-Enable-support-for-multiple-net_devices.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 80369686737fe07c233a1152da0b84372dabdcd6 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:15 +0100 -Subject: [PATCH 07/15] net: airoha: Enable support for multiple net_devices - -In the current codebase airoha_eth driver supports just a single -net_device connected to the Packet Switch Engine (PSE) lan port (GDM1). -As shown in commit 23020f049327 ("net: airoha: Introduce ethernet -support for EN7581 SoC"), PSE can switch packets between four GDM ports. -Enable the capability to create a net_device for each GDM port of the -PSE module. Moreover, since the QDMA blocks can be shared between -net_devices, do not stop TX/RX DMA in airoha_dev_stop() if there are -active net_devices for this QDMA block. -This is a preliminary patch to enable flowtable hw offloading for EN7581 -SoC. - -Co-developed-by: Christian Marangi -Signed-off-by: Christian Marangi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 35 ++++++++++++++---------- - drivers/net/ethernet/airoha/airoha_eth.h | 4 ++- - 2 files changed, 24 insertions(+), 15 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1583,6 +1583,7 @@ static int airoha_dev_open(struct net_de - airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, - GLOBAL_CFG_TX_DMA_EN_MASK | - GLOBAL_CFG_RX_DMA_EN_MASK); -+ atomic_inc(&qdma->users); - - return 0; - } -@@ -1598,16 +1599,20 @@ static int airoha_dev_stop(struct net_de - if (err) - return err; - -- airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, -- GLOBAL_CFG_TX_DMA_EN_MASK | -- GLOBAL_CFG_RX_DMA_EN_MASK); -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) -+ netdev_tx_reset_subqueue(dev, i); - -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -- if (!qdma->q_tx[i].ndesc) -- continue; -+ if (atomic_dec_and_test(&qdma->users)) { -+ airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, -+ GLOBAL_CFG_TX_DMA_EN_MASK | -+ GLOBAL_CFG_RX_DMA_EN_MASK); -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -+ if (!qdma->q_tx[i].ndesc) -+ continue; - -- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -- netdev_tx_reset_subqueue(dev, i); -+ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -+ } - } - - return 0; -@@ -2350,13 +2355,14 @@ static void airoha_metadata_dst_free(str - } - } - --static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np) -+static int airoha_alloc_gdm_port(struct airoha_eth *eth, -+ struct device_node *np, int index) - { - const __be32 *id_ptr = of_get_property(np, "reg", NULL); - struct airoha_gdm_port *port; - struct airoha_qdma *qdma; - struct net_device *dev; -- int err, index; -+ int err, p; - u32 id; - - if (!id_ptr) { -@@ -2365,14 +2371,14 @@ static int airoha_alloc_gdm_port(struct - } - - id = be32_to_cpup(id_ptr); -- index = id - 1; -+ p = id - 1; - - if (!id || id > ARRAY_SIZE(eth->ports)) { - dev_err(eth->dev, "invalid gdm port id: %d\n", id); - return -EINVAL; - } - -- if (eth->ports[index]) { -+ if (eth->ports[p]) { - dev_err(eth->dev, "duplicate gdm port id: %d\n", id); - return -EINVAL; - } -@@ -2420,7 +2426,7 @@ static int airoha_alloc_gdm_port(struct - port->qdma = qdma; - port->dev = dev; - port->id = id; -- eth->ports[index] = port; -+ eth->ports[p] = port; - - err = airoha_metadata_dst_alloc(port); - if (err) -@@ -2492,6 +2498,7 @@ static int airoha_probe(struct platform_ - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) - airoha_qdma_start_napi(ð->qdma[i]); - -+ i = 0; - for_each_child_of_node(pdev->dev.of_node, np) { - if (!of_device_is_compatible(np, "airoha,eth-mac")) - continue; -@@ -2499,7 +2506,7 @@ static int airoha_probe(struct platform_ - if (!of_device_is_available(np)) - continue; - -- err = airoha_alloc_gdm_port(eth, np); -+ err = airoha_alloc_gdm_port(eth, np, i++); - if (err) { - of_node_put(np); - goto error_napi_stop; ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -13,7 +13,7 @@ - #include - #include - --#define AIROHA_MAX_NUM_GDM_PORTS 1 -+#define AIROHA_MAX_NUM_GDM_PORTS 4 - #define AIROHA_MAX_NUM_QDMA 2 - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 -@@ -212,6 +212,8 @@ struct airoha_qdma { - u32 irqmask[QDMA_INT_REG_MAX]; - int irq; - -+ atomic_t users; -+ - struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; - - struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; diff --git a/target/linux/airoha/patches-6.12/048-08-v6.15-net-airoha-Move-REG_GDM_FWD_CFG-initialization-in-ai.patch b/target/linux/airoha/patches-6.12/048-08-v6.15-net-airoha-Move-REG_GDM_FWD_CFG-initialization-in-ai.patch deleted file mode 100644 index 4edf38bf9a4..00000000000 --- a/target/linux/airoha/patches-6.12/048-08-v6.15-net-airoha-Move-REG_GDM_FWD_CFG-initialization-in-ai.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 67fde5d58cd43d129a979e918ec9cd5d2e2fbcfb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:16 +0100 -Subject: [PATCH 08/15] net: airoha: Move REG_GDM_FWD_CFG() initialization in - airoha_dev_init() - -Move REG_GDM_FWD_CFG() register initialization in airoha_dev_init -routine. Moreover, always send traffic PPE module in order to be -processed by hw accelerator. -This is a preliminary patch to enable netfilter flowtable hw offloading -on EN7581 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -107,25 +107,20 @@ static void airoha_set_gdm_port_fwd_cfg( - - static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) - { -- u32 val = enable ? FE_PSE_PORT_PPE1 : FE_PSE_PORT_DROP; -- u32 vip_port, cfg_addr; -+ u32 vip_port; - - switch (port) { - case XSI_PCIE0_PORT: - vip_port = XSI_PCIE0_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(3); - break; - case XSI_PCIE1_PORT: - vip_port = XSI_PCIE1_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(3); - break; - case XSI_USB_PORT: - vip_port = XSI_USB_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(4); - break; - case XSI_ETH_PORT: - vip_port = XSI_ETH_VIP_PORT_MASK; -- cfg_addr = REG_GDM_FWD_CFG(4); - break; - default: - return -EINVAL; -@@ -139,8 +134,6 @@ static int airoha_set_gdm_port(struct ai - airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port); - } - -- airoha_set_gdm_port_fwd_cfg(eth, cfg_addr, val); -- - return 0; - } - -@@ -177,8 +170,6 @@ static void airoha_fe_maccr_init(struct - airoha_fe_set(eth, REG_GDM_FWD_CFG(p), - GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | - GDM_DROP_CRC_ERR); -- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(p), -- FE_PSE_PORT_CDM1); - airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), - GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, - FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -@@ -1635,8 +1626,11 @@ static int airoha_dev_set_macaddr(struct - static int airoha_dev_init(struct net_device *dev) - { - struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_eth *eth = port->qdma->eth; - - airoha_set_macaddr(port, dev->dev_addr); -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), -+ FE_PSE_PORT_PPE1); - - return 0; - } diff --git a/target/linux/airoha/patches-6.12/048-09-v6.15-net-airoha-Rename-airoha_set_gdm_port_fwd_cfg-in-air.patch b/target/linux/airoha/patches-6.12/048-09-v6.15-net-airoha-Rename-airoha_set_gdm_port_fwd_cfg-in-air.patch deleted file mode 100644 index fb2dfed9b3f..00000000000 --- a/target/linux/airoha/patches-6.12/048-09-v6.15-net-airoha-Rename-airoha_set_gdm_port_fwd_cfg-in-air.patch +++ /dev/null @@ -1,120 +0,0 @@ -From c28b8375f6d02ef3b5e8c51234cc3f6d47d9fb7f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:17 +0100 -Subject: [PATCH 09/15] net: airoha: Rename airoha_set_gdm_port_fwd_cfg() in - airoha_set_vip_for_gdm_port() - -Rename airoha_set_gdm_port() in airoha_set_vip_for_gdm_port(). -Get rid of airoha_set_gdm_ports routine. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 49 ++++++------------------ - drivers/net/ethernet/airoha/airoha_eth.h | 8 ---- - 2 files changed, 11 insertions(+), 46 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -105,25 +105,23 @@ static void airoha_set_gdm_port_fwd_cfg( - FIELD_PREP(GDM_UCFQ_MASK, val)); - } - --static int airoha_set_gdm_port(struct airoha_eth *eth, int port, bool enable) -+static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port, -+ bool enable) - { -+ struct airoha_eth *eth = port->qdma->eth; - u32 vip_port; - -- switch (port) { -- case XSI_PCIE0_PORT: -+ switch (port->id) { -+ case 3: -+ /* FIXME: handle XSI_PCIE1_PORT */ - vip_port = XSI_PCIE0_VIP_PORT_MASK; - break; -- case XSI_PCIE1_PORT: -- vip_port = XSI_PCIE1_VIP_PORT_MASK; -- break; -- case XSI_USB_PORT: -- vip_port = XSI_USB_VIP_PORT_MASK; -- break; -- case XSI_ETH_PORT: -+ case 4: -+ /* FIXME: handle XSI_USB_PORT */ - vip_port = XSI_ETH_VIP_PORT_MASK; - break; - default: -- return -EINVAL; -+ return 0; - } - - if (enable) { -@@ -137,31 +135,6 @@ static int airoha_set_gdm_port(struct ai - return 0; - } - --static int airoha_set_gdm_ports(struct airoha_eth *eth, bool enable) --{ -- const int port_list[] = { -- XSI_PCIE0_PORT, -- XSI_PCIE1_PORT, -- XSI_USB_PORT, -- XSI_ETH_PORT -- }; -- int i, err; -- -- for (i = 0; i < ARRAY_SIZE(port_list); i++) { -- err = airoha_set_gdm_port(eth, port_list[i], enable); -- if (err) -- goto error; -- } -- -- return 0; -- --error: -- for (i--; i >= 0; i--) -- airoha_set_gdm_port(eth, port_list[i], false); -- -- return err; --} -- - static void airoha_fe_maccr_init(struct airoha_eth *eth) - { - int p; -@@ -1560,7 +1533,7 @@ static int airoha_dev_open(struct net_de - int err; - - netif_tx_start_all_queues(dev); -- err = airoha_set_gdm_ports(qdma->eth, true); -+ err = airoha_set_vip_for_gdm_port(port, true); - if (err) - return err; - -@@ -1586,7 +1559,7 @@ static int airoha_dev_stop(struct net_de - int i, err; - - netif_tx_disable(dev); -- err = airoha_set_gdm_ports(qdma->eth, false); -+ err = airoha_set_vip_for_gdm_port(port, false); - if (err) - return err; - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -58,14 +58,6 @@ enum { - }; - - enum { -- XSI_PCIE0_PORT, -- XSI_PCIE1_PORT, -- XSI_USB_PORT, -- XSI_AE_PORT, -- XSI_ETH_PORT, --}; -- --enum { - XSI_PCIE0_VIP_PORT_MASK = BIT(22), - XSI_PCIE1_VIP_PORT_MASK = BIT(23), - XSI_USB_VIP_PORT_MASK = BIT(25), diff --git a/target/linux/airoha/patches-6.12/048-12-v6.15-net-airoha-Introduce-Airoha-NPU-support.patch b/target/linux/airoha/patches-6.12/048-12-v6.15-net-airoha-Introduce-Airoha-NPU-support.patch deleted file mode 100644 index 41c56223040..00000000000 --- a/target/linux/airoha/patches-6.12/048-12-v6.15-net-airoha-Introduce-Airoha-NPU-support.patch +++ /dev/null @@ -1,627 +0,0 @@ -From 23290c7bc190def4e1ca61610992d9b7c32e33f3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:20 +0100 -Subject: [PATCH 12/15] net: airoha: Introduce Airoha NPU support - -Packet Processor Engine (PPE) module available on EN7581 SoC populates -the PPE table with 5-tuples flower rules learned from traffic forwarded -between the GDM ports connected to the Packet Switch Engine (PSE) module. -The airoha_eth driver can enable hw acceleration of learned 5-tuples -rules if the user configure them in netfilter flowtable (netfilter -flowtable support will be added with subsequent patches). -airoha_eth driver configures and collects data from the PPE module via a -Network Processor Unit (NPU) RISC-V module available on the EN7581 SoC. -Introduce basic support for Airoha NPU module. - -Tested-by: Sayantan Nandy -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/Kconfig | 9 + - drivers/net/ethernet/airoha/Makefile | 1 + - drivers/net/ethernet/airoha/airoha_eth.h | 2 + - drivers/net/ethernet/airoha/airoha_npu.c | 520 +++++++++++++++++++++++ - drivers/net/ethernet/airoha/airoha_npu.h | 34 ++ - 5 files changed, 566 insertions(+) - create mode 100644 drivers/net/ethernet/airoha/airoha_npu.c - create mode 100644 drivers/net/ethernet/airoha/airoha_npu.h - ---- a/drivers/net/ethernet/airoha/Kconfig -+++ b/drivers/net/ethernet/airoha/Kconfig -@@ -7,9 +7,18 @@ config NET_VENDOR_AIROHA - - if NET_VENDOR_AIROHA - -+config NET_AIROHA_NPU -+ tristate "Airoha NPU support" -+ select WANT_DEV_COREDUMP -+ select REGMAP_MMIO -+ help -+ This driver supports Airoha Network Processor (NPU) available -+ on the Airoha Soc family. -+ - config NET_AIROHA - tristate "Airoha SoC Gigabit Ethernet support" - depends on NET_DSA || !NET_DSA -+ select NET_AIROHA_NPU - select PAGE_POOL - help - This driver supports the gigabit ethernet MACs in the ---- a/drivers/net/ethernet/airoha/Makefile -+++ b/drivers/net/ethernet/airoha/Makefile -@@ -4,3 +4,4 @@ - # - - obj-$(CONFIG_NET_AIROHA) += airoha_eth.o -+obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -240,6 +240,8 @@ struct airoha_eth { - unsigned long state; - void __iomem *fe_regs; - -+ struct airoha_npu __rcu *npu; -+ - struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; - struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; - ---- /dev/null -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -0,0 +1,520 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2025 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "airoha_npu.h" -+ -+#define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" -+#define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" -+#define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 -+#define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 -+#define NPU_DUMP_SIZE 512 -+ -+#define REG_NPU_LOCAL_SRAM 0x0 -+ -+#define NPU_PC_BASE_ADDR 0x305000 -+#define REG_PC_DBG(_n) (0x305000 + ((_n) * 0x100)) -+ -+#define NPU_CLUSTER_BASE_ADDR 0x306000 -+ -+#define REG_CR_BOOT_TRIGGER (NPU_CLUSTER_BASE_ADDR + 0x000) -+#define REG_CR_BOOT_CONFIG (NPU_CLUSTER_BASE_ADDR + 0x004) -+#define REG_CR_BOOT_BASE(_n) (NPU_CLUSTER_BASE_ADDR + 0x020 + ((_n) << 2)) -+ -+#define NPU_MBOX_BASE_ADDR 0x30c000 -+ -+#define REG_CR_MBOX_INT_STATUS (NPU_MBOX_BASE_ADDR + 0x000) -+#define MBOX_INT_STATUS_MASK BIT(8) -+ -+#define REG_CR_MBOX_INT_MASK(_n) (NPU_MBOX_BASE_ADDR + 0x004 + ((_n) << 2)) -+#define REG_CR_MBQ0_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x030 + ((_n) << 2)) -+#define REG_CR_MBQ8_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x0b0 + ((_n) << 2)) -+#define REG_CR_NPU_MIB(_n) (NPU_MBOX_BASE_ADDR + 0x140 + ((_n) << 2)) -+ -+#define NPU_TIMER_BASE_ADDR 0x310100 -+#define REG_WDT_TIMER_CTRL(_n) (NPU_TIMER_BASE_ADDR + ((_n) * 0x100)) -+#define WDT_EN_MASK BIT(25) -+#define WDT_INTR_MASK BIT(21) -+ -+enum { -+ NPU_OP_SET = 1, -+ NPU_OP_SET_NO_WAIT, -+ NPU_OP_GET, -+ NPU_OP_GET_NO_WAIT, -+}; -+ -+enum { -+ NPU_FUNC_WIFI, -+ NPU_FUNC_TUNNEL, -+ NPU_FUNC_NOTIFY, -+ NPU_FUNC_DBA, -+ NPU_FUNC_TR471, -+ NPU_FUNC_PPE, -+}; -+ -+enum { -+ NPU_MBOX_ERROR, -+ NPU_MBOX_SUCCESS, -+}; -+ -+enum { -+ PPE_FUNC_SET_WAIT, -+ PPE_FUNC_SET_WAIT_HWNAT_INIT, -+ PPE_FUNC_SET_WAIT_HWNAT_DEINIT, -+ PPE_FUNC_SET_WAIT_API, -+}; -+ -+enum { -+ PPE2_SRAM_SET_ENTRY, -+ PPE_SRAM_SET_ENTRY, -+ PPE_SRAM_SET_VAL, -+ PPE_SRAM_RESET_VAL, -+}; -+ -+enum { -+ QDMA_WAN_ETHER = 1, -+ QDMA_WAN_PON_XDSL, -+}; -+ -+#define MBOX_MSG_FUNC_ID GENMASK(14, 11) -+#define MBOX_MSG_STATIC_BUF BIT(5) -+#define MBOX_MSG_STATUS GENMASK(4, 2) -+#define MBOX_MSG_DONE BIT(1) -+#define MBOX_MSG_WAIT_RSP BIT(0) -+ -+#define PPE_TYPE_L2B_IPV4 2 -+#define PPE_TYPE_L2B_IPV4_IPV6 3 -+ -+struct ppe_mbox_data { -+ u32 func_type; -+ u32 func_id; -+ union { -+ struct { -+ u8 cds; -+ u8 xpon_hal_api; -+ u8 wan_xsi; -+ u8 ct_joyme4; -+ int ppe_type; -+ int wan_mode; -+ int wan_sel; -+ } init_info; -+ struct { -+ int func_id; -+ u32 size; -+ u32 data; -+ } set_info; -+ }; -+}; -+ -+static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, -+ void *p, int size) -+{ -+ u16 core = 0; /* FIXME */ -+ u32 val, offset = core << 4; -+ dma_addr_t dma_addr; -+ void *addr; -+ int ret; -+ -+ addr = kmemdup(p, size, GFP_ATOMIC); -+ if (!addr) -+ return -ENOMEM; -+ -+ dma_addr = dma_map_single(npu->dev, addr, size, DMA_TO_DEVICE); -+ ret = dma_mapping_error(npu->dev, dma_addr); -+ if (ret) -+ goto out; -+ -+ spin_lock_bh(&npu->cores[core].lock); -+ -+ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(0) + offset, dma_addr); -+ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(1) + offset, size); -+ regmap_read(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, &val); -+ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(2) + offset, val + 1); -+ val = FIELD_PREP(MBOX_MSG_FUNC_ID, func_id) | MBOX_MSG_WAIT_RSP; -+ regmap_write(npu->regmap, REG_CR_MBQ0_CTRL(3) + offset, val); -+ -+ ret = regmap_read_poll_timeout_atomic(npu->regmap, -+ REG_CR_MBQ0_CTRL(3) + offset, -+ val, (val & MBOX_MSG_DONE), -+ 100, 100 * MSEC_PER_SEC); -+ if (!ret && FIELD_GET(MBOX_MSG_STATUS, val) != NPU_MBOX_SUCCESS) -+ ret = -EINVAL; -+ -+ spin_unlock_bh(&npu->cores[core].lock); -+ -+ dma_unmap_single(npu->dev, dma_addr, size, DMA_TO_DEVICE); -+out: -+ kfree(addr); -+ -+ return ret; -+} -+ -+static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, -+ struct reserved_mem *rmem) -+{ -+ const struct firmware *fw; -+ void __iomem *addr; -+ int ret; -+ -+ ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); -+ if (ret) -+ return ret == -ENOENT ? -EPROBE_DEFER : ret; -+ -+ if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) { -+ dev_err(dev, "%s: fw size too overlimit (%zu)\n", -+ NPU_EN7581_FIRMWARE_RV32, fw->size); -+ ret = -E2BIG; -+ goto out; -+ } -+ -+ addr = devm_ioremap(dev, rmem->base, rmem->size); -+ if (!addr) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ memcpy_toio(addr, fw->data, fw->size); -+ release_firmware(fw); -+ -+ ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); -+ if (ret) -+ return ret == -ENOENT ? -EPROBE_DEFER : ret; -+ -+ if (fw->size > NPU_EN7581_FIRMWARE_DATA_MAX_SIZE) { -+ dev_err(dev, "%s: fw size too overlimit (%zu)\n", -+ NPU_EN7581_FIRMWARE_DATA, fw->size); -+ ret = -E2BIG; -+ goto out; -+ } -+ -+ memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size); -+out: -+ release_firmware(fw); -+ -+ return ret; -+} -+ -+static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) -+{ -+ struct airoha_npu *npu = npu_instance; -+ -+ /* clear mbox interrupt status */ -+ regmap_write(npu->regmap, REG_CR_MBOX_INT_STATUS, -+ MBOX_INT_STATUS_MASK); -+ -+ /* acknowledge npu */ -+ regmap_update_bits(npu->regmap, REG_CR_MBQ8_CTRL(3), -+ MBOX_MSG_STATUS | MBOX_MSG_DONE, MBOX_MSG_DONE); -+ -+ return IRQ_HANDLED; -+} -+ -+static void airoha_npu_wdt_work(struct work_struct *work) -+{ -+ struct airoha_npu_core *core; -+ struct airoha_npu *npu; -+ void *dump; -+ u32 val[3]; -+ int c; -+ -+ core = container_of(work, struct airoha_npu_core, wdt_work); -+ npu = core->npu; -+ -+ dump = vzalloc(NPU_DUMP_SIZE); -+ if (!dump) -+ return; -+ -+ c = core - &npu->cores[0]; -+ regmap_bulk_read(npu->regmap, REG_PC_DBG(c), val, ARRAY_SIZE(val)); -+ snprintf(dump, NPU_DUMP_SIZE, "PC: %08x SP: %08x LR: %08x\n", -+ val[0], val[1], val[2]); -+ -+ dev_coredumpv(npu->dev, dump, NPU_DUMP_SIZE, GFP_KERNEL); -+} -+ -+static irqreturn_t airoha_npu_wdt_handler(int irq, void *core_instance) -+{ -+ struct airoha_npu_core *core = core_instance; -+ struct airoha_npu *npu = core->npu; -+ int c = core - &npu->cores[0]; -+ u32 val; -+ -+ regmap_set_bits(npu->regmap, REG_WDT_TIMER_CTRL(c), WDT_INTR_MASK); -+ if (!regmap_read(npu->regmap, REG_WDT_TIMER_CTRL(c), &val) && -+ FIELD_GET(WDT_EN_MASK, val)) -+ schedule_work(&core->wdt_work); -+ -+ return IRQ_HANDLED; -+} -+ -+static int airoha_npu_ppe_init(struct airoha_npu *npu) -+{ -+ struct ppe_mbox_data ppe_data = { -+ .func_type = NPU_OP_SET, -+ .func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT, -+ .init_info = { -+ .ppe_type = PPE_TYPE_L2B_IPV4_IPV6, -+ .wan_mode = QDMA_WAN_ETHER, -+ }, -+ }; -+ -+ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -+ sizeof(struct ppe_mbox_data)); -+} -+ -+static int airoha_npu_ppe_deinit(struct airoha_npu *npu) -+{ -+ struct ppe_mbox_data ppe_data = { -+ .func_type = NPU_OP_SET, -+ .func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT, -+ }; -+ -+ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -+ sizeof(struct ppe_mbox_data)); -+} -+ -+static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu, -+ dma_addr_t foe_addr, -+ int sram_num_entries) -+{ -+ struct ppe_mbox_data ppe_data = { -+ .func_type = NPU_OP_SET, -+ .func_id = PPE_FUNC_SET_WAIT_API, -+ .set_info = { -+ .func_id = PPE_SRAM_RESET_VAL, -+ .data = foe_addr, -+ .size = sram_num_entries, -+ }, -+ }; -+ -+ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -+ sizeof(struct ppe_mbox_data)); -+} -+ -+static int airoha_npu_foe_commit_entry(struct airoha_npu *npu, -+ dma_addr_t foe_addr, -+ u32 entry_size, u32 hash, bool ppe2) -+{ -+ struct ppe_mbox_data ppe_data = { -+ .func_type = NPU_OP_SET, -+ .func_id = PPE_FUNC_SET_WAIT_API, -+ .set_info = { -+ .data = foe_addr, -+ .size = entry_size, -+ }, -+ }; -+ int err; -+ -+ ppe_data.set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY -+ : PPE_SRAM_SET_ENTRY; -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -+ sizeof(struct ppe_mbox_data)); -+ if (err) -+ return err; -+ -+ ppe_data.set_info.func_id = PPE_SRAM_SET_VAL; -+ ppe_data.set_info.data = hash; -+ ppe_data.set_info.size = sizeof(u32); -+ -+ return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -+ sizeof(struct ppe_mbox_data)); -+} -+ -+struct airoha_npu *airoha_npu_get(struct device *dev) -+{ -+ struct platform_device *pdev; -+ struct device_node *np; -+ struct airoha_npu *npu; -+ -+ np = of_parse_phandle(dev->of_node, "airoha,npu", 0); -+ if (!np) -+ return ERR_PTR(-ENODEV); -+ -+ pdev = of_find_device_by_node(np); -+ of_node_put(np); -+ -+ if (!pdev) { -+ dev_err(dev, "cannot find device node %s\n", np->name); -+ return ERR_PTR(-ENODEV); -+ } -+ -+ if (!try_module_get(THIS_MODULE)) { -+ dev_err(dev, "failed to get the device driver module\n"); -+ npu = ERR_PTR(-ENODEV); -+ goto error_pdev_put; -+ } -+ -+ npu = platform_get_drvdata(pdev); -+ if (!npu) { -+ npu = ERR_PTR(-ENODEV); -+ goto error_module_put; -+ } -+ -+ if (!device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER)) { -+ dev_err(&pdev->dev, -+ "failed to create device link to consumer %s\n", -+ dev_name(dev)); -+ npu = ERR_PTR(-EINVAL); -+ goto error_module_put; -+ } -+ -+ return npu; -+ -+error_module_put: -+ module_put(THIS_MODULE); -+error_pdev_put: -+ platform_device_put(pdev); -+ -+ return npu; -+} -+EXPORT_SYMBOL_GPL(airoha_npu_get); -+ -+void airoha_npu_put(struct airoha_npu *npu) -+{ -+ module_put(THIS_MODULE); -+ put_device(npu->dev); -+} -+EXPORT_SYMBOL_GPL(airoha_npu_put); -+ -+static const struct of_device_id of_airoha_npu_match[] = { -+ { .compatible = "airoha,en7581-npu" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, of_airoha_npu_match); -+ -+static const struct regmap_config regmap_config = { -+ .name = "npu", -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .disable_locking = true, -+}; -+ -+static int airoha_npu_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct reserved_mem *rmem; -+ struct airoha_npu *npu; -+ struct device_node *np; -+ void __iomem *base; -+ int i, irq, err; -+ -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ npu = devm_kzalloc(dev, sizeof(*npu), GFP_KERNEL); -+ if (!npu) -+ return -ENOMEM; -+ -+ npu->dev = dev; -+ npu->ops.ppe_init = airoha_npu_ppe_init; -+ npu->ops.ppe_deinit = airoha_npu_ppe_deinit; -+ npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; -+ npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; -+ -+ npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); -+ if (IS_ERR(npu->regmap)) -+ return PTR_ERR(npu->regmap); -+ -+ np = of_parse_phandle(dev->of_node, "memory-region", 0); -+ if (!np) -+ return -ENODEV; -+ -+ rmem = of_reserved_mem_lookup(np); -+ of_node_put(np); -+ -+ if (!rmem) -+ return -ENODEV; -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+ -+ err = devm_request_irq(dev, irq, airoha_npu_mbox_handler, -+ IRQF_SHARED, "airoha-npu-mbox", npu); -+ if (err) -+ return err; -+ -+ for (i = 0; i < ARRAY_SIZE(npu->cores); i++) { -+ struct airoha_npu_core *core = &npu->cores[i]; -+ -+ spin_lock_init(&core->lock); -+ core->npu = npu; -+ -+ irq = platform_get_irq(pdev, i + 1); -+ if (irq < 0) -+ return irq; -+ -+ err = devm_request_irq(dev, irq, airoha_npu_wdt_handler, -+ IRQF_SHARED, "airoha-npu-wdt", core); -+ if (err) -+ return err; -+ -+ INIT_WORK(&core->wdt_work, airoha_npu_wdt_work); -+ } -+ -+ err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); -+ if (err) -+ return err; -+ -+ err = airoha_npu_run_firmware(dev, base, rmem); -+ if (err) -+ return dev_err_probe(dev, err, "failed to run npu firmware\n"); -+ -+ regmap_write(npu->regmap, REG_CR_NPU_MIB(10), -+ rmem->base + NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); -+ regmap_write(npu->regmap, REG_CR_NPU_MIB(11), 0x40000); /* SRAM 256K */ -+ regmap_write(npu->regmap, REG_CR_NPU_MIB(12), 0); -+ regmap_write(npu->regmap, REG_CR_NPU_MIB(21), 1); -+ msleep(100); -+ -+ /* setting booting address */ -+ for (i = 0; i < NPU_NUM_CORES; i++) -+ regmap_write(npu->regmap, REG_CR_BOOT_BASE(i), rmem->base); -+ usleep_range(1000, 2000); -+ -+ /* enable NPU cores */ -+ /* do not start core3 since it is used for WiFi offloading */ -+ regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xf7); -+ regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); -+ msleep(100); -+ -+ platform_set_drvdata(pdev, npu); -+ -+ return 0; -+} -+ -+static void airoha_npu_remove(struct platform_device *pdev) -+{ -+ struct airoha_npu *npu = platform_get_drvdata(pdev); -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(npu->cores); i++) -+ cancel_work_sync(&npu->cores[i].wdt_work); -+} -+ -+static struct platform_driver airoha_npu_driver = { -+ .probe = airoha_npu_probe, -+ .remove_new = airoha_npu_remove, -+ .driver = { -+ .name = "airoha-npu", -+ .of_match_table = of_airoha_npu_match, -+ }, -+}; -+module_platform_driver(airoha_npu_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Lorenzo Bianconi "); -+MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); ---- /dev/null -+++ b/drivers/net/ethernet/airoha/airoha_npu.h -@@ -0,0 +1,34 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2025 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#define NPU_NUM_CORES 8 -+ -+struct airoha_npu { -+ struct device *dev; -+ struct regmap *regmap; -+ -+ struct airoha_npu_core { -+ struct airoha_npu *npu; -+ /* protect concurrent npu memory accesses */ -+ spinlock_t lock; -+ struct work_struct wdt_work; -+ } cores[NPU_NUM_CORES]; -+ -+ struct { -+ int (*ppe_init)(struct airoha_npu *npu); -+ int (*ppe_deinit)(struct airoha_npu *npu); -+ int (*ppe_flush_sram_entries)(struct airoha_npu *npu, -+ dma_addr_t foe_addr, -+ int sram_num_entries); -+ int (*ppe_foe_commit_entry)(struct airoha_npu *npu, -+ dma_addr_t foe_addr, -+ u32 entry_size, u32 hash, -+ bool ppe2); -+ } ops; -+}; -+ -+struct airoha_npu *airoha_npu_get(struct device *dev); -+void airoha_npu_put(struct airoha_npu *npu); diff --git a/target/linux/airoha/patches-6.12/048-13-v6.15-net-airoha-Introduce-flowtable-offload-support.patch b/target/linux/airoha/patches-6.12/048-13-v6.15-net-airoha-Introduce-flowtable-offload-support.patch deleted file mode 100644 index bb2394acc1c..00000000000 --- a/target/linux/airoha/patches-6.12/048-13-v6.15-net-airoha-Introduce-flowtable-offload-support.patch +++ /dev/null @@ -1,1481 +0,0 @@ -From 00a7678310fe3d3f408513e55d9a0b67f0db380f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:21 +0100 -Subject: [PATCH 13/15] net: airoha: Introduce flowtable offload support - -Introduce netfilter flowtable integration in order to allow airoha_eth -driver to offload 5-tuple flower rules learned by the PPE module if the -user accelerates them using a nft configuration similar to the one reported -below: - -table inet filter { - flowtable ft { - hook ingress priority filter - devices = { lan1, lan2, lan3, lan4, eth1 } - flags offload; - } - chain forward { - type filter hook forward priority filter; policy accept; - meta l4proto { tcp, udp } flow add @ft - } -} - -Tested-by: Sayantan Nandy -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/Makefile | 3 +- - drivers/net/ethernet/airoha/airoha_eth.c | 60 +- - drivers/net/ethernet/airoha/airoha_eth.h | 250 ++++++ - drivers/net/ethernet/airoha/airoha_ppe.c | 901 ++++++++++++++++++++++ - drivers/net/ethernet/airoha/airoha_regs.h | 107 ++- - 5 files changed, 1314 insertions(+), 7 deletions(-) - create mode 100644 drivers/net/ethernet/airoha/airoha_ppe.c - ---- a/drivers/net/ethernet/airoha/Makefile -+++ b/drivers/net/ethernet/airoha/Makefile -@@ -3,5 +3,6 @@ - # Airoha for the Mediatek SoCs built-in ethernet macs - # - --obj-$(CONFIG_NET_AIROHA) += airoha_eth.o -+obj-$(CONFIG_NET_AIROHA) += airoha-eth.o -+airoha-eth-y := airoha_eth.o airoha_ppe.o - obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -8,7 +8,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -619,6 +618,7 @@ static int airoha_qdma_rx_process(struct - while (done < budget) { - struct airoha_queue_entry *e = &q->entry[q->tail]; - struct airoha_qdma_desc *desc = &q->desc[q->tail]; -+ u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); - dma_addr_t dma_addr = le32_to_cpu(desc->addr); - u32 desc_ctrl = le32_to_cpu(desc->ctrl); - struct airoha_gdm_port *port; -@@ -681,6 +681,15 @@ static int airoha_qdma_rx_process(struct - &port->dsa_meta[sptag]->dst); - } - -+ hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1); -+ if (hash != AIROHA_RXD4_FOE_ENTRY) -+ skb_set_hash(skb, jhash_1word(hash, 0), -+ PKT_HASH_TYPE_L4); -+ -+ reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); -+ if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -+ airoha_ppe_check_skb(eth->ppe, hash); -+ - napi_gro_receive(&q->napi, skb); - - done++; -@@ -1322,6 +1331,10 @@ static int airoha_hw_init(struct platfor - return err; - } - -+ err = airoha_ppe_init(eth); -+ if (err) -+ return err; -+ - set_bit(DEV_STATE_INITIALIZED, ð->state); - - return 0; -@@ -2186,6 +2199,47 @@ static int airoha_tc_htb_alloc_leaf_queu - return 0; - } - -+static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port, -+ struct flow_block_offload *f) -+{ -+ flow_setup_cb_t *cb = airoha_ppe_setup_tc_block_cb; -+ static LIST_HEAD(block_cb_list); -+ struct flow_block_cb *block_cb; -+ -+ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) -+ return -EOPNOTSUPP; -+ -+ f->driver_block_list = &block_cb_list; -+ switch (f->command) { -+ case FLOW_BLOCK_BIND: -+ block_cb = flow_block_cb_lookup(f->block, cb, port->dev); -+ if (block_cb) { -+ flow_block_cb_incref(block_cb); -+ return 0; -+ } -+ block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL); -+ if (IS_ERR(block_cb)) -+ return PTR_ERR(block_cb); -+ -+ flow_block_cb_incref(block_cb); -+ flow_block_cb_add(block_cb, f); -+ list_add_tail(&block_cb->driver_list, &block_cb_list); -+ return 0; -+ case FLOW_BLOCK_UNBIND: -+ block_cb = flow_block_cb_lookup(f->block, cb, port->dev); -+ if (!block_cb) -+ return -ENOENT; -+ -+ if (!flow_block_cb_decref(block_cb)) { -+ flow_block_cb_remove(block_cb, f); -+ list_del(&block_cb->driver_list); -+ } -+ return 0; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) - { - struct net_device *dev = port->dev; -@@ -2269,6 +2323,9 @@ static int airoha_dev_tc_setup(struct ne - return airoha_tc_setup_qdisc_ets(port, type_data); - case TC_SETUP_QDISC_HTB: - return airoha_tc_setup_qdisc_htb(port, type_data); -+ case TC_SETUP_BLOCK: -+ case TC_SETUP_FT: -+ return airoha_dev_setup_tc_block(port, type_data); - default: - return -EOPNOTSUPP; - } -@@ -2524,6 +2581,7 @@ static void airoha_remove(struct platfor - } - free_netdev(eth->napi_dev); - -+ airoha_ppe_deinit(eth); - platform_set_drvdata(pdev, NULL); - } - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #define AIROHA_MAX_NUM_GDM_PORTS 4 - #define AIROHA_MAX_NUM_QDMA 2 -@@ -44,6 +45,15 @@ - #define QDMA_METER_IDX(_n) ((_n) & 0xff) - #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) - -+#define PPE_NUM 2 -+#define PPE1_SRAM_NUM_ENTRIES (8 * 1024) -+#define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) -+#define PPE_DRAM_NUM_ENTRIES (16 * 1024) -+#define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) -+#define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) -+#define PPE_ENTRY_SIZE 80 -+#define PPE_RAM_NUM_ENTRIES_SHIFT(_n) (__ffs((_n) >> 10)) -+ - #define MTK_HDR_LEN 4 - #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 - #define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 -@@ -195,6 +205,224 @@ struct airoha_hw_stats { - u64 rx_len[7]; - }; - -+enum { -+ PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, -+}; -+ -+enum { -+ AIROHA_FOE_STATE_INVALID, -+ AIROHA_FOE_STATE_UNBIND, -+ AIROHA_FOE_STATE_BIND, -+ AIROHA_FOE_STATE_FIN -+}; -+ -+enum { -+ PPE_PKT_TYPE_IPV4_HNAPT = 0, -+ PPE_PKT_TYPE_IPV4_ROUTE = 1, -+ PPE_PKT_TYPE_BRIDGE = 2, -+ PPE_PKT_TYPE_IPV4_DSLITE = 3, -+ PPE_PKT_TYPE_IPV6_ROUTE_3T = 4, -+ PPE_PKT_TYPE_IPV6_ROUTE_5T = 5, -+ PPE_PKT_TYPE_IPV6_6RD = 7, -+}; -+ -+#define AIROHA_FOE_MAC_SMAC_ID GENMASK(20, 16) -+#define AIROHA_FOE_MAC_PPPOE_ID GENMASK(15, 0) -+ -+struct airoha_foe_mac_info_common { -+ u16 vlan1; -+ u16 etype; -+ -+ u32 dest_mac_hi; -+ -+ u16 vlan2; -+ u16 dest_mac_lo; -+ -+ u32 src_mac_hi; -+}; -+ -+struct airoha_foe_mac_info { -+ struct airoha_foe_mac_info_common common; -+ -+ u16 pppoe_id; -+ u16 src_mac_lo; -+}; -+ -+#define AIROHA_FOE_IB1_UNBIND_PREBIND BIT(24) -+#define AIROHA_FOE_IB1_UNBIND_PACKETS GENMASK(23, 8) -+#define AIROHA_FOE_IB1_UNBIND_TIMESTAMP GENMASK(7, 0) -+ -+#define AIROHA_FOE_IB1_BIND_STATIC BIT(31) -+#define AIROHA_FOE_IB1_BIND_UDP BIT(30) -+#define AIROHA_FOE_IB1_BIND_STATE GENMASK(29, 28) -+#define AIROHA_FOE_IB1_BIND_PACKET_TYPE GENMASK(27, 25) -+#define AIROHA_FOE_IB1_BIND_TTL BIT(24) -+#define AIROHA_FOE_IB1_BIND_TUNNEL_DECAP BIT(23) -+#define AIROHA_FOE_IB1_BIND_PPPOE BIT(22) -+#define AIROHA_FOE_IB1_BIND_VPM GENMASK(21, 20) -+#define AIROHA_FOE_IB1_BIND_VLAN_LAYER GENMASK(19, 16) -+#define AIROHA_FOE_IB1_BIND_KEEPALIVE BIT(15) -+#define AIROHA_FOE_IB1_BIND_TIMESTAMP GENMASK(14, 0) -+ -+#define AIROHA_FOE_IB2_DSCP GENMASK(31, 24) -+#define AIROHA_FOE_IB2_PORT_AG GENMASK(23, 13) -+#define AIROHA_FOE_IB2_PCP BIT(12) -+#define AIROHA_FOE_IB2_MULTICAST BIT(11) -+#define AIROHA_FOE_IB2_FAST_PATH BIT(10) -+#define AIROHA_FOE_IB2_PSE_QOS BIT(9) -+#define AIROHA_FOE_IB2_PSE_PORT GENMASK(8, 5) -+#define AIROHA_FOE_IB2_NBQ GENMASK(4, 0) -+ -+#define AIROHA_FOE_ACTDP GENMASK(31, 24) -+#define AIROHA_FOE_SHAPER_ID GENMASK(23, 16) -+#define AIROHA_FOE_CHANNEL GENMASK(15, 11) -+#define AIROHA_FOE_QID GENMASK(10, 8) -+#define AIROHA_FOE_DPI BIT(7) -+#define AIROHA_FOE_TUNNEL BIT(6) -+#define AIROHA_FOE_TUNNEL_ID GENMASK(5, 0) -+ -+struct airoha_foe_bridge { -+ u32 dest_mac_hi; -+ -+ u16 src_mac_hi; -+ u16 dest_mac_lo; -+ -+ u32 src_mac_lo; -+ -+ u32 ib2; -+ -+ u32 rsv[5]; -+ -+ u32 data; -+ -+ struct airoha_foe_mac_info l2; -+}; -+ -+struct airoha_foe_ipv4_tuple { -+ u32 src_ip; -+ u32 dest_ip; -+ union { -+ struct { -+ u16 dest_port; -+ u16 src_port; -+ }; -+ struct { -+ u8 protocol; -+ u8 _pad[3]; /* fill with 0xa5a5a5 */ -+ }; -+ u32 ports; -+ }; -+}; -+ -+struct airoha_foe_ipv4 { -+ struct airoha_foe_ipv4_tuple orig_tuple; -+ -+ u32 ib2; -+ -+ struct airoha_foe_ipv4_tuple new_tuple; -+ -+ u32 rsv[2]; -+ -+ u32 data; -+ -+ struct airoha_foe_mac_info l2; -+}; -+ -+struct airoha_foe_ipv4_dslite { -+ struct airoha_foe_ipv4_tuple ip4; -+ -+ u32 ib2; -+ -+ u8 flow_label[3]; -+ u8 priority; -+ -+ u32 rsv[4]; -+ -+ u32 data; -+ -+ struct airoha_foe_mac_info l2; -+}; -+ -+struct airoha_foe_ipv6 { -+ u32 src_ip[4]; -+ u32 dest_ip[4]; -+ -+ union { -+ struct { -+ u16 dest_port; -+ u16 src_port; -+ }; -+ struct { -+ u8 protocol; -+ u8 pad[3]; -+ }; -+ u32 ports; -+ }; -+ -+ u32 data; -+ -+ u32 ib2; -+ -+ struct airoha_foe_mac_info_common l2; -+}; -+ -+struct airoha_foe_entry { -+ union { -+ struct { -+ u32 ib1; -+ union { -+ struct airoha_foe_bridge bridge; -+ struct airoha_foe_ipv4 ipv4; -+ struct airoha_foe_ipv4_dslite dslite; -+ struct airoha_foe_ipv6 ipv6; -+ DECLARE_FLEX_ARRAY(u32, d); -+ }; -+ }; -+ u8 data[PPE_ENTRY_SIZE]; -+ }; -+}; -+ -+struct airoha_flow_data { -+ struct ethhdr eth; -+ -+ union { -+ struct { -+ __be32 src_addr; -+ __be32 dst_addr; -+ } v4; -+ -+ struct { -+ struct in6_addr src_addr; -+ struct in6_addr dst_addr; -+ } v6; -+ }; -+ -+ __be16 src_port; -+ __be16 dst_port; -+ -+ struct { -+ struct { -+ u16 id; -+ __be16 proto; -+ } hdr[2]; -+ u8 num; -+ } vlan; -+ struct { -+ u16 sid; -+ u8 num; -+ } pppoe; -+}; -+ -+struct airoha_flow_table_entry { -+ struct hlist_node list; -+ -+ struct airoha_foe_entry data; -+ u32 hash; -+ -+ struct rhash_head node; -+ unsigned long cookie; -+}; -+ - struct airoha_qdma { - struct airoha_eth *eth; - void __iomem *regs; -@@ -234,6 +462,19 @@ struct airoha_gdm_port { - struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; - }; - -+#define AIROHA_RXD4_PPE_CPU_REASON GENMASK(20, 16) -+#define AIROHA_RXD4_FOE_ENTRY GENMASK(15, 0) -+ -+struct airoha_ppe { -+ struct airoha_eth *eth; -+ -+ void *foe; -+ dma_addr_t foe_dma; -+ -+ struct hlist_head *foe_flow; -+ u16 foe_check_time[PPE_NUM_ENTRIES]; -+}; -+ - struct airoha_eth { - struct device *dev; - -@@ -242,6 +483,9 @@ struct airoha_eth { - - struct airoha_npu __rcu *npu; - -+ struct airoha_ppe *ppe; -+ struct rhashtable flow_table; -+ - struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; - struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; - -@@ -277,4 +521,10 @@ u32 airoha_rmw(void __iomem *base, u32 o - #define airoha_qdma_clear(qdma, offset, val) \ - airoha_rmw((qdma)->regs, (offset), (val), 0) - -+void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); -+int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, -+ void *cb_priv); -+int airoha_ppe_init(struct airoha_eth *eth); -+void airoha_ppe_deinit(struct airoha_eth *eth); -+ - #endif /* AIROHA_ETH_H */ ---- /dev/null -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -0,0 +1,901 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2025 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "airoha_npu.h" -+#include "airoha_regs.h" -+#include "airoha_eth.h" -+ -+static DEFINE_MUTEX(flow_offload_mutex); -+static DEFINE_SPINLOCK(ppe_lock); -+ -+static const struct rhashtable_params airoha_flow_table_params = { -+ .head_offset = offsetof(struct airoha_flow_table_entry, node), -+ .key_offset = offsetof(struct airoha_flow_table_entry, cookie), -+ .key_len = sizeof(unsigned long), -+ .automatic_shrinking = true, -+}; -+ -+static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) -+{ -+ return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; -+} -+ -+static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) -+{ -+ u16 timestamp = airoha_fe_rr(ppe->eth, REG_FE_FOE_TS); -+ -+ return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); -+} -+ -+static void airoha_ppe_hw_init(struct airoha_ppe *ppe) -+{ -+ u32 sram_tb_size, sram_num_entries, dram_num_entries; -+ struct airoha_eth *eth = ppe->eth; -+ int i; -+ -+ sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); -+ dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); -+ -+ for (i = 0; i < PPE_NUM; i++) { -+ int p; -+ -+ airoha_fe_wr(eth, REG_PPE_TB_BASE(i), -+ ppe->foe_dma + sram_tb_size); -+ -+ airoha_fe_rmw(eth, REG_PPE_BND_AGE0(i), -+ PPE_BIND_AGE0_DELTA_NON_L4 | -+ PPE_BIND_AGE0_DELTA_UDP, -+ FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 1) | -+ FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 12)); -+ airoha_fe_rmw(eth, REG_PPE_BND_AGE1(i), -+ PPE_BIND_AGE1_DELTA_TCP_FIN | -+ PPE_BIND_AGE1_DELTA_TCP, -+ FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP_FIN, 1) | -+ FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 7)); -+ -+ airoha_fe_rmw(eth, REG_PPE_TB_HASH_CFG(i), -+ PPE_SRAM_TABLE_EN_MASK | -+ PPE_SRAM_HASH1_EN_MASK | -+ PPE_DRAM_TABLE_EN_MASK | -+ PPE_SRAM_HASH0_MODE_MASK | -+ PPE_SRAM_HASH1_MODE_MASK | -+ PPE_DRAM_HASH0_MODE_MASK | -+ PPE_DRAM_HASH1_MODE_MASK, -+ FIELD_PREP(PPE_SRAM_TABLE_EN_MASK, 1) | -+ FIELD_PREP(PPE_SRAM_HASH1_EN_MASK, 1) | -+ FIELD_PREP(PPE_SRAM_HASH1_MODE_MASK, 1) | -+ FIELD_PREP(PPE_DRAM_HASH1_MODE_MASK, 3)); -+ -+ airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), -+ PPE_TB_CFG_SEARCH_MISS_MASK | -+ PPE_TB_ENTRY_SIZE_MASK, -+ FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | -+ FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); -+ -+ airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); -+ -+ for (p = 0; p < ARRAY_SIZE(eth->ports); p++) -+ airoha_fe_rmw(eth, REG_PPE_MTU(i, p), -+ FP0_EGRESS_MTU_MASK | -+ FP1_EGRESS_MTU_MASK, -+ FIELD_PREP(FP0_EGRESS_MTU_MASK, -+ AIROHA_MAX_MTU) | -+ FIELD_PREP(FP1_EGRESS_MTU_MASK, -+ AIROHA_MAX_MTU)); -+ } -+ -+ if (airoha_ppe2_is_enabled(eth)) { -+ sram_num_entries = -+ PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_ENTRIES); -+ airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), -+ PPE_SRAM_TB_NUM_ENTRY_MASK | -+ PPE_DRAM_TB_NUM_ENTRY_MASK, -+ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, -+ sram_num_entries) | -+ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, -+ dram_num_entries)); -+ airoha_fe_rmw(eth, REG_PPE_TB_CFG(1), -+ PPE_SRAM_TB_NUM_ENTRY_MASK | -+ PPE_DRAM_TB_NUM_ENTRY_MASK, -+ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, -+ sram_num_entries) | -+ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, -+ dram_num_entries)); -+ } else { -+ sram_num_entries = -+ PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_ENTRIES); -+ airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), -+ PPE_SRAM_TB_NUM_ENTRY_MASK | -+ PPE_DRAM_TB_NUM_ENTRY_MASK, -+ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, -+ sram_num_entries) | -+ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, -+ dram_num_entries)); -+ } -+} -+ -+static void airoha_ppe_flow_mangle_eth(const struct flow_action_entry *act, void *eth) -+{ -+ void *dest = eth + act->mangle.offset; -+ const void *src = &act->mangle.val; -+ -+ if (act->mangle.offset > 8) -+ return; -+ -+ if (act->mangle.mask == 0xffff) { -+ src += 2; -+ dest += 2; -+ } -+ -+ memcpy(dest, src, act->mangle.mask ? 2 : 4); -+} -+ -+static int airoha_ppe_flow_mangle_ports(const struct flow_action_entry *act, -+ struct airoha_flow_data *data) -+{ -+ u32 val = be32_to_cpu((__force __be32)act->mangle.val); -+ -+ switch (act->mangle.offset) { -+ case 0: -+ if ((__force __be32)act->mangle.mask == ~cpu_to_be32(0xffff)) -+ data->dst_port = cpu_to_be16(val); -+ else -+ data->src_port = cpu_to_be16(val >> 16); -+ break; -+ case 2: -+ data->dst_port = cpu_to_be16(val); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int airoha_ppe_flow_mangle_ipv4(const struct flow_action_entry *act, -+ struct airoha_flow_data *data) -+{ -+ __be32 *dest; -+ -+ switch (act->mangle.offset) { -+ case offsetof(struct iphdr, saddr): -+ dest = &data->v4.src_addr; -+ break; -+ case offsetof(struct iphdr, daddr): -+ dest = &data->v4.dst_addr; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ memcpy(dest, &act->mangle.val, sizeof(u32)); -+ -+ return 0; -+} -+ -+static int airoha_get_dsa_port(struct net_device **dev) -+{ -+#if IS_ENABLED(CONFIG_NET_DSA) -+ struct dsa_port *dp = dsa_port_from_netdev(*dev); -+ -+ if (IS_ERR(dp)) -+ return -ENODEV; -+ -+ *dev = dsa_port_to_conduit(dp); -+ return dp->index; -+#else -+ return -ENODEV; -+#endif -+} -+ -+static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, -+ struct net_device *dev, int type, -+ struct airoha_flow_data *data, -+ int l4proto) -+{ -+ int dsa_port = airoha_get_dsa_port(&dev); -+ struct airoha_foe_mac_info_common *l2; -+ u32 qdata, ports_pad, val; -+ -+ memset(hwe, 0, sizeof(*hwe)); -+ -+ val = FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, AIROHA_FOE_STATE_BIND) | -+ FIELD_PREP(AIROHA_FOE_IB1_BIND_PACKET_TYPE, type) | -+ FIELD_PREP(AIROHA_FOE_IB1_BIND_UDP, l4proto == IPPROTO_UDP) | -+ FIELD_PREP(AIROHA_FOE_IB1_BIND_VLAN_LAYER, data->vlan.num) | -+ FIELD_PREP(AIROHA_FOE_IB1_BIND_VPM, data->vlan.num) | -+ AIROHA_FOE_IB1_BIND_TTL; -+ hwe->ib1 = val; -+ -+ val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); -+ if (dsa_port >= 0) -+ val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port); -+ -+ if (dev) { -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ u8 pse_port; -+ -+ pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; -+ val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); -+ } -+ -+ /* FIXME: implement QoS support setting pse_port to 2 (loopback) -+ * for uplink and setting qos bit in ib2 -+ */ -+ -+ if (is_multicast_ether_addr(data->eth.h_dest)) -+ val |= AIROHA_FOE_IB2_MULTICAST; -+ -+ ports_pad = 0xa5a5a500 | (l4proto & 0xff); -+ if (type == PPE_PKT_TYPE_IPV4_ROUTE) -+ hwe->ipv4.orig_tuple.ports = ports_pad; -+ if (type == PPE_PKT_TYPE_IPV6_ROUTE_3T) -+ hwe->ipv6.ports = ports_pad; -+ -+ qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f); -+ if (type == PPE_PKT_TYPE_BRIDGE) { -+ hwe->bridge.dest_mac_hi = get_unaligned_be32(data->eth.h_dest); -+ hwe->bridge.dest_mac_lo = -+ get_unaligned_be16(data->eth.h_dest + 4); -+ hwe->bridge.src_mac_hi = -+ get_unaligned_be16(data->eth.h_source); -+ hwe->bridge.src_mac_lo = -+ get_unaligned_be32(data->eth.h_source + 2); -+ hwe->bridge.data = qdata; -+ hwe->bridge.ib2 = val; -+ l2 = &hwe->bridge.l2.common; -+ } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { -+ hwe->ipv6.data = qdata; -+ hwe->ipv6.ib2 = val; -+ l2 = &hwe->ipv6.l2; -+ } else { -+ hwe->ipv4.data = qdata; -+ hwe->ipv4.ib2 = val; -+ l2 = &hwe->ipv4.l2.common; -+ } -+ -+ l2->dest_mac_hi = get_unaligned_be32(data->eth.h_dest); -+ l2->dest_mac_lo = get_unaligned_be16(data->eth.h_dest + 4); -+ if (type <= PPE_PKT_TYPE_IPV4_DSLITE) { -+ l2->src_mac_hi = get_unaligned_be32(data->eth.h_source); -+ hwe->ipv4.l2.src_mac_lo = -+ get_unaligned_be16(data->eth.h_source + 4); -+ } else { -+ l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, 0xf); -+ } -+ -+ if (data->vlan.num) { -+ l2->etype = dsa_port >= 0 ? BIT(dsa_port) : 0; -+ l2->vlan1 = data->vlan.hdr[0].id; -+ if (data->vlan.num == 2) -+ l2->vlan2 = data->vlan.hdr[1].id; -+ } else if (dsa_port >= 0) { -+ l2->etype = BIT(15) | BIT(dsa_port); -+ } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { -+ l2->etype = ETH_P_IPV6; -+ } else { -+ l2->etype = ETH_P_IP; -+ } -+ -+ return 0; -+} -+ -+static int airoha_ppe_foe_entry_set_ipv4_tuple(struct airoha_foe_entry *hwe, -+ struct airoha_flow_data *data, -+ bool egress) -+{ -+ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); -+ struct airoha_foe_ipv4_tuple *t; -+ -+ switch (type) { -+ case PPE_PKT_TYPE_IPV4_HNAPT: -+ if (egress) { -+ t = &hwe->ipv4.new_tuple; -+ break; -+ } -+ fallthrough; -+ case PPE_PKT_TYPE_IPV4_DSLITE: -+ case PPE_PKT_TYPE_IPV4_ROUTE: -+ t = &hwe->ipv4.orig_tuple; -+ break; -+ default: -+ WARN_ON_ONCE(1); -+ return -EINVAL; -+ } -+ -+ t->src_ip = be32_to_cpu(data->v4.src_addr); -+ t->dest_ip = be32_to_cpu(data->v4.dst_addr); -+ -+ if (type != PPE_PKT_TYPE_IPV4_ROUTE) { -+ t->src_port = be16_to_cpu(data->src_port); -+ t->dest_port = be16_to_cpu(data->dst_port); -+ } -+ -+ return 0; -+} -+ -+static int airoha_ppe_foe_entry_set_ipv6_tuple(struct airoha_foe_entry *hwe, -+ struct airoha_flow_data *data) -+ -+{ -+ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); -+ u32 *src, *dest; -+ -+ switch (type) { -+ case PPE_PKT_TYPE_IPV6_ROUTE_5T: -+ case PPE_PKT_TYPE_IPV6_6RD: -+ hwe->ipv6.src_port = be16_to_cpu(data->src_port); -+ hwe->ipv6.dest_port = be16_to_cpu(data->dst_port); -+ fallthrough; -+ case PPE_PKT_TYPE_IPV6_ROUTE_3T: -+ src = hwe->ipv6.src_ip; -+ dest = hwe->ipv6.dest_ip; -+ break; -+ default: -+ WARN_ON_ONCE(1); -+ return -EINVAL; -+ } -+ -+ ipv6_addr_be32_to_cpu(src, data->v6.src_addr.s6_addr32); -+ ipv6_addr_be32_to_cpu(dest, data->v6.dst_addr.s6_addr32); -+ -+ return 0; -+} -+ -+static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe) -+{ -+ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); -+ u32 hash, hv1, hv2, hv3; -+ -+ switch (type) { -+ case PPE_PKT_TYPE_IPV4_ROUTE: -+ case PPE_PKT_TYPE_IPV4_HNAPT: -+ hv1 = hwe->ipv4.orig_tuple.ports; -+ hv2 = hwe->ipv4.orig_tuple.dest_ip; -+ hv3 = hwe->ipv4.orig_tuple.src_ip; -+ break; -+ case PPE_PKT_TYPE_IPV6_ROUTE_3T: -+ case PPE_PKT_TYPE_IPV6_ROUTE_5T: -+ hv1 = hwe->ipv6.src_ip[3] ^ hwe->ipv6.dest_ip[3]; -+ hv1 ^= hwe->ipv6.ports; -+ -+ hv2 = hwe->ipv6.src_ip[2] ^ hwe->ipv6.dest_ip[2]; -+ hv2 ^= hwe->ipv6.dest_ip[0]; -+ -+ hv3 = hwe->ipv6.src_ip[1] ^ hwe->ipv6.dest_ip[1]; -+ hv3 ^= hwe->ipv6.src_ip[0]; -+ break; -+ case PPE_PKT_TYPE_IPV4_DSLITE: -+ case PPE_PKT_TYPE_IPV6_6RD: -+ default: -+ WARN_ON_ONCE(1); -+ return PPE_HASH_MASK; -+ } -+ -+ hash = (hv1 & hv2) | ((~hv1) & hv3); -+ hash = (hash >> 24) | ((hash & 0xffffff) << 8); -+ hash ^= hv1 ^ hv2 ^ hv3; -+ hash ^= hash >> 16; -+ hash &= PPE_NUM_ENTRIES - 1; -+ -+ return hash; -+} -+ -+static struct airoha_foe_entry * -+airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, u32 hash) -+{ -+ if (hash < PPE_SRAM_NUM_ENTRIES) { -+ u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); -+ struct airoha_eth *eth = ppe->eth; -+ bool ppe2; -+ u32 val; -+ int i; -+ -+ ppe2 = airoha_ppe2_is_enabled(ppe->eth) && -+ hash >= PPE1_SRAM_NUM_ENTRIES; -+ airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), -+ FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | -+ PPE_SRAM_CTRL_REQ_MASK); -+ if (read_poll_timeout_atomic(airoha_fe_rr, val, -+ val & PPE_SRAM_CTRL_ACK_MASK, -+ 10, 100, false, eth, -+ REG_PPE_RAM_CTRL(ppe2))) -+ return NULL; -+ -+ for (i = 0; i < sizeof(struct airoha_foe_entry) / 4; i++) -+ hwe[i] = airoha_fe_rr(eth, -+ REG_PPE_RAM_ENTRY(ppe2, i)); -+ } -+ -+ return ppe->foe + hash * sizeof(struct airoha_foe_entry); -+} -+ -+static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e, -+ struct airoha_foe_entry *hwe) -+{ -+ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, e->data.ib1); -+ int len; -+ -+ if ((hwe->ib1 ^ e->data.ib1) & AIROHA_FOE_IB1_BIND_UDP) -+ return false; -+ -+ if (type > PPE_PKT_TYPE_IPV4_DSLITE) -+ len = offsetof(struct airoha_foe_entry, ipv6.data); -+ else -+ len = offsetof(struct airoha_foe_entry, ipv4.ib2); -+ -+ return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1)); -+} -+ -+static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, -+ struct airoha_foe_entry *e, -+ u32 hash) -+{ -+ struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); -+ u32 ts = airoha_ppe_get_timestamp(ppe); -+ struct airoha_eth *eth = ppe->eth; -+ -+ memcpy(&hwe->d, &e->d, sizeof(*hwe) - sizeof(hwe->ib1)); -+ wmb(); -+ -+ e->ib1 &= ~AIROHA_FOE_IB1_BIND_TIMESTAMP; -+ e->ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_TIMESTAMP, ts); -+ hwe->ib1 = e->ib1; -+ -+ if (hash < PPE_SRAM_NUM_ENTRIES) { -+ dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); -+ bool ppe2 = airoha_ppe2_is_enabled(eth) && -+ hash >= PPE1_SRAM_NUM_ENTRIES; -+ struct airoha_npu *npu; -+ int err = -ENODEV; -+ -+ rcu_read_lock(); -+ npu = rcu_dereference(eth->npu); -+ if (npu) -+ err = npu->ops.ppe_foe_commit_entry(npu, addr, -+ sizeof(*hwe), hash, -+ ppe2); -+ rcu_read_unlock(); -+ -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, u32 hash) -+{ -+ struct airoha_flow_table_entry *e; -+ struct airoha_foe_entry *hwe; -+ struct hlist_node *n; -+ u32 index, state; -+ -+ spin_lock_bh(&ppe_lock); -+ -+ hwe = airoha_ppe_foe_get_entry(ppe, hash); -+ if (!hwe) -+ goto unlock; -+ -+ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); -+ if (state == AIROHA_FOE_STATE_BIND) -+ goto unlock; -+ -+ index = airoha_ppe_foe_get_entry_hash(hwe); -+ hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { -+ if (airoha_ppe_foe_compare_entry(e, hwe)) { -+ airoha_ppe_foe_commit_entry(ppe, &e->data, hash); -+ e->hash = hash; -+ break; -+ } -+ } -+unlock: -+ spin_unlock_bh(&ppe_lock); -+} -+ -+static int airoha_ppe_foe_flow_commit_entry(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ u32 hash = airoha_ppe_foe_get_entry_hash(&e->data); -+ -+ e->hash = 0xffff; -+ -+ spin_lock_bh(&ppe_lock); -+ hlist_add_head(&e->list, &ppe->foe_flow[hash]); -+ spin_unlock_bh(&ppe_lock); -+ -+ return 0; -+} -+ -+static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ spin_lock_bh(&ppe_lock); -+ -+ hlist_del_init(&e->list); -+ if (e->hash != 0xffff) { -+ e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; -+ e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, -+ AIROHA_FOE_STATE_INVALID); -+ airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); -+ e->hash = 0xffff; -+ } -+ -+ spin_unlock_bh(&ppe_lock); -+} -+ -+static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, -+ struct flow_cls_offload *f) -+{ -+ struct flow_rule *rule = flow_cls_offload_flow_rule(f); -+ struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_flow_table_entry *e; -+ struct airoha_flow_data data = {}; -+ struct net_device *odev = NULL; -+ struct flow_action_entry *act; -+ struct airoha_foe_entry hwe; -+ int err, i, offload_type; -+ u16 addr_type = 0; -+ u8 l4proto = 0; -+ -+ if (rhashtable_lookup(ð->flow_table, &f->cookie, -+ airoha_flow_table_params)) -+ return -EEXIST; -+ -+ if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) -+ return -EOPNOTSUPP; -+ -+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) { -+ struct flow_match_control match; -+ -+ flow_rule_match_control(rule, &match); -+ addr_type = match.key->addr_type; -+ if (flow_rule_has_control_flags(match.mask->flags, -+ f->common.extack)) -+ return -EOPNOTSUPP; -+ } else { -+ return -EOPNOTSUPP; -+ } -+ -+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { -+ struct flow_match_basic match; -+ -+ flow_rule_match_basic(rule, &match); -+ l4proto = match.key->ip_proto; -+ } else { -+ return -EOPNOTSUPP; -+ } -+ -+ switch (addr_type) { -+ case 0: -+ offload_type = PPE_PKT_TYPE_BRIDGE; -+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { -+ struct flow_match_eth_addrs match; -+ -+ flow_rule_match_eth_addrs(rule, &match); -+ memcpy(data.eth.h_dest, match.key->dst, ETH_ALEN); -+ memcpy(data.eth.h_source, match.key->src, ETH_ALEN); -+ } else { -+ return -EOPNOTSUPP; -+ } -+ break; -+ case FLOW_DISSECTOR_KEY_IPV4_ADDRS: -+ offload_type = PPE_PKT_TYPE_IPV4_HNAPT; -+ break; -+ case FLOW_DISSECTOR_KEY_IPV6_ADDRS: -+ offload_type = PPE_PKT_TYPE_IPV6_ROUTE_5T; -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ flow_action_for_each(i, act, &rule->action) { -+ switch (act->id) { -+ case FLOW_ACTION_MANGLE: -+ if (offload_type == PPE_PKT_TYPE_BRIDGE) -+ return -EOPNOTSUPP; -+ -+ if (act->mangle.htype == FLOW_ACT_MANGLE_HDR_TYPE_ETH) -+ airoha_ppe_flow_mangle_eth(act, &data.eth); -+ break; -+ case FLOW_ACTION_REDIRECT: -+ odev = act->dev; -+ break; -+ case FLOW_ACTION_CSUM: -+ break; -+ case FLOW_ACTION_VLAN_PUSH: -+ if (data.vlan.num == 2 || -+ act->vlan.proto != htons(ETH_P_8021Q)) -+ return -EOPNOTSUPP; -+ -+ data.vlan.hdr[data.vlan.num].id = act->vlan.vid; -+ data.vlan.hdr[data.vlan.num].proto = act->vlan.proto; -+ data.vlan.num++; -+ break; -+ case FLOW_ACTION_VLAN_POP: -+ break; -+ case FLOW_ACTION_PPPOE_PUSH: -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ } -+ -+ if (!is_valid_ether_addr(data.eth.h_source) || -+ !is_valid_ether_addr(data.eth.h_dest)) -+ return -EINVAL; -+ -+ err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type, -+ &data, l4proto); -+ if (err) -+ return err; -+ -+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { -+ struct flow_match_ports ports; -+ -+ if (offload_type == PPE_PKT_TYPE_BRIDGE) -+ return -EOPNOTSUPP; -+ -+ flow_rule_match_ports(rule, &ports); -+ data.src_port = ports.key->src; -+ data.dst_port = ports.key->dst; -+ } else if (offload_type != PPE_PKT_TYPE_BRIDGE) { -+ return -EOPNOTSUPP; -+ } -+ -+ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { -+ struct flow_match_ipv4_addrs addrs; -+ -+ flow_rule_match_ipv4_addrs(rule, &addrs); -+ data.v4.src_addr = addrs.key->src; -+ data.v4.dst_addr = addrs.key->dst; -+ airoha_ppe_foe_entry_set_ipv4_tuple(&hwe, &data, false); -+ } -+ -+ if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { -+ struct flow_match_ipv6_addrs addrs; -+ -+ flow_rule_match_ipv6_addrs(rule, &addrs); -+ -+ data.v6.src_addr = addrs.key->src; -+ data.v6.dst_addr = addrs.key->dst; -+ airoha_ppe_foe_entry_set_ipv6_tuple(&hwe, &data); -+ } -+ -+ flow_action_for_each(i, act, &rule->action) { -+ if (act->id != FLOW_ACTION_MANGLE) -+ continue; -+ -+ if (offload_type == PPE_PKT_TYPE_BRIDGE) -+ return -EOPNOTSUPP; -+ -+ switch (act->mangle.htype) { -+ case FLOW_ACT_MANGLE_HDR_TYPE_TCP: -+ case FLOW_ACT_MANGLE_HDR_TYPE_UDP: -+ err = airoha_ppe_flow_mangle_ports(act, &data); -+ break; -+ case FLOW_ACT_MANGLE_HDR_TYPE_IP4: -+ err = airoha_ppe_flow_mangle_ipv4(act, &data); -+ break; -+ case FLOW_ACT_MANGLE_HDR_TYPE_ETH: -+ /* handled earlier */ -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ if (err) -+ return err; -+ } -+ -+ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { -+ err = airoha_ppe_foe_entry_set_ipv4_tuple(&hwe, &data, true); -+ if (err) -+ return err; -+ } -+ -+ e = kzalloc(sizeof(*e), GFP_KERNEL); -+ if (!e) -+ return -ENOMEM; -+ -+ e->cookie = f->cookie; -+ memcpy(&e->data, &hwe, sizeof(e->data)); -+ -+ err = airoha_ppe_foe_flow_commit_entry(eth->ppe, e); -+ if (err) -+ goto free_entry; -+ -+ err = rhashtable_insert_fast(ð->flow_table, &e->node, -+ airoha_flow_table_params); -+ if (err < 0) -+ goto remove_foe_entry; -+ -+ return 0; -+ -+remove_foe_entry: -+ airoha_ppe_foe_flow_remove_entry(eth->ppe, e); -+free_entry: -+ kfree(e); -+ -+ return err; -+} -+ -+static int airoha_ppe_flow_offload_destroy(struct airoha_gdm_port *port, -+ struct flow_cls_offload *f) -+{ -+ struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_flow_table_entry *e; -+ -+ e = rhashtable_lookup(ð->flow_table, &f->cookie, -+ airoha_flow_table_params); -+ if (!e) -+ return -ENOENT; -+ -+ airoha_ppe_foe_flow_remove_entry(eth->ppe, e); -+ rhashtable_remove_fast(ð->flow_table, &e->node, -+ airoha_flow_table_params); -+ kfree(e); -+ -+ return 0; -+} -+ -+static int airoha_ppe_flow_offload_cmd(struct airoha_gdm_port *port, -+ struct flow_cls_offload *f) -+{ -+ switch (f->command) { -+ case FLOW_CLS_REPLACE: -+ return airoha_ppe_flow_offload_replace(port, f); -+ case FLOW_CLS_DESTROY: -+ return airoha_ppe_flow_offload_destroy(port, f); -+ default: -+ break; -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, -+ struct airoha_npu *npu) -+{ -+ int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; -+ struct airoha_foe_entry *hwe = ppe->foe; -+ -+ if (airoha_ppe2_is_enabled(ppe->eth)) -+ sram_num_entries = sram_num_entries / 2; -+ -+ for (i = 0; i < sram_num_entries; i++) -+ memset(&hwe[i], 0, sizeof(*hwe)); -+ -+ return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, -+ PPE_SRAM_NUM_ENTRIES); -+} -+ -+static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) -+{ -+ struct airoha_npu *npu = airoha_npu_get(eth->dev); -+ -+ if (IS_ERR(npu)) { -+ request_module("airoha-npu"); -+ npu = airoha_npu_get(eth->dev); -+ } -+ -+ return npu; -+} -+ -+static int airoha_ppe_offload_setup(struct airoha_eth *eth) -+{ -+ struct airoha_npu *npu = airoha_ppe_npu_get(eth); -+ int err; -+ -+ if (IS_ERR(npu)) -+ return PTR_ERR(npu); -+ -+ err = npu->ops.ppe_init(npu); -+ if (err) -+ goto error_npu_put; -+ -+ airoha_ppe_hw_init(eth->ppe); -+ err = airoha_ppe_flush_sram_entries(eth->ppe, npu); -+ if (err) -+ goto error_npu_put; -+ -+ rcu_assign_pointer(eth->npu, npu); -+ synchronize_rcu(); -+ -+ return 0; -+ -+error_npu_put: -+ airoha_npu_put(npu); -+ -+ return err; -+} -+ -+int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, -+ void *cb_priv) -+{ -+ struct flow_cls_offload *cls = type_data; -+ struct net_device *dev = cb_priv; -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_eth *eth = port->qdma->eth; -+ int err = 0; -+ -+ if (!tc_can_offload(dev) || type != TC_SETUP_CLSFLOWER) -+ return -EOPNOTSUPP; -+ -+ mutex_lock(&flow_offload_mutex); -+ -+ if (!eth->npu) -+ err = airoha_ppe_offload_setup(eth); -+ if (!err) -+ err = airoha_ppe_flow_offload_cmd(port, cls); -+ -+ mutex_unlock(&flow_offload_mutex); -+ -+ return err; -+} -+ -+void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash) -+{ -+ u16 now, diff; -+ -+ if (hash > PPE_HASH_MASK) -+ return; -+ -+ now = (u16)jiffies; -+ diff = now - ppe->foe_check_time[hash]; -+ if (diff < HZ / 10) -+ return; -+ -+ ppe->foe_check_time[hash] = now; -+ airoha_ppe_foe_insert_entry(ppe, hash); -+} -+ -+int airoha_ppe_init(struct airoha_eth *eth) -+{ -+ struct airoha_ppe *ppe; -+ int foe_size; -+ -+ ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); -+ if (!ppe) -+ return -ENOMEM; -+ -+ foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); -+ ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, -+ GFP_KERNEL); -+ if (!ppe->foe) -+ return -ENOMEM; -+ -+ ppe->eth = eth; -+ eth->ppe = ppe; -+ -+ ppe->foe_flow = devm_kzalloc(eth->dev, -+ PPE_NUM_ENTRIES * sizeof(*ppe->foe_flow), -+ GFP_KERNEL); -+ if (!ppe->foe_flow) -+ return -ENOMEM; -+ -+ return rhashtable_init(ð->flow_table, &airoha_flow_table_params); -+} -+ -+void airoha_ppe_deinit(struct airoha_eth *eth) -+{ -+ struct airoha_npu *npu; -+ -+ rcu_read_lock(); -+ npu = rcu_dereference(eth->npu); -+ if (npu) { -+ npu->ops.ppe_deinit(npu); -+ airoha_npu_put(npu); -+ } -+ rcu_read_unlock(); -+ -+ rhashtable_destroy(ð->flow_table); -+} ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -15,6 +15,7 @@ - #define CDM1_BASE 0x0400 - #define GDM1_BASE 0x0500 - #define PPE1_BASE 0x0c00 -+#define PPE2_BASE 0x1c00 - - #define CDM2_BASE 0x1400 - #define GDM2_BASE 0x1500 -@@ -36,6 +37,7 @@ - #define FE_RST_GDM3_MBI_ARB_MASK BIT(2) - #define FE_RST_CORE_MASK BIT(0) - -+#define REG_FE_FOE_TS 0x0010 - #define REG_FE_WAN_MAC_H 0x0030 - #define REG_FE_LAN_MAC_H 0x0040 - -@@ -192,11 +194,106 @@ - #define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) - #define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) - --#define REG_PPE1_TB_HASH_CFG (PPE1_BASE + 0x250) --#define PPE1_SRAM_TABLE_EN_MASK BIT(0) --#define PPE1_SRAM_HASH1_EN_MASK BIT(8) --#define PPE1_DRAM_TABLE_EN_MASK BIT(16) --#define PPE1_DRAM_HASH1_EN_MASK BIT(24) -+#define REG_PPE_GLO_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x200) -+#define PPE_GLO_CFG_BUSY_MASK BIT(31) -+#define PPE_GLO_CFG_FLOW_DROP_UPDATE_MASK BIT(9) -+#define PPE_GLO_CFG_PSE_HASH_OFS_MASK BIT(6) -+#define PPE_GLO_CFG_PPE_BSWAP_MASK BIT(5) -+#define PPE_GLO_CFG_TTL_DROP_MASK BIT(4) -+#define PPE_GLO_CFG_IP4_CS_DROP_MASK BIT(3) -+#define PPE_GLO_CFG_IP4_L4_CS_DROP_MASK BIT(2) -+#define PPE_GLO_CFG_EN_MASK BIT(0) -+ -+#define REG_PPE_PPE_FLOW_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x204) -+#define PPE_FLOW_CFG_IP6_HASH_GRE_KEY_MASK BIT(20) -+#define PPE_FLOW_CFG_IP4_HASH_GRE_KEY_MASK BIT(19) -+#define PPE_FLOW_CFG_IP4_HASH_FLOW_LABEL_MASK BIT(18) -+#define PPE_FLOW_CFG_IP4_NAT_FRAG_MASK BIT(17) -+#define PPE_FLOW_CFG_IP_PROTO_BLACKLIST_MASK BIT(16) -+#define PPE_FLOW_CFG_IP4_DSLITE_MASK BIT(14) -+#define PPE_FLOW_CFG_IP4_NAPT_MASK BIT(13) -+#define PPE_FLOW_CFG_IP4_NAT_MASK BIT(12) -+#define PPE_FLOW_CFG_IP6_6RD_MASK BIT(10) -+#define PPE_FLOW_CFG_IP6_5T_ROUTE_MASK BIT(9) -+#define PPE_FLOW_CFG_IP6_3T_ROUTE_MASK BIT(8) -+#define PPE_FLOW_CFG_IP4_UDP_FRAG_MASK BIT(7) -+#define PPE_FLOW_CFG_IP4_TCP_FRAG_MASK BIT(6) -+ -+#define REG_PPE_IP_PROTO_CHK(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x208) -+#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(15, 0) -+#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(31, 16) -+ -+#define REG_PPE_TB_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x21c) -+#define PPE_SRAM_TB_NUM_ENTRY_MASK GENMASK(26, 24) -+#define PPE_TB_CFG_KEEPALIVE_MASK GENMASK(13, 12) -+#define PPE_TB_CFG_AGE_TCP_FIN_MASK BIT(11) -+#define PPE_TB_CFG_AGE_UDP_MASK BIT(10) -+#define PPE_TB_CFG_AGE_TCP_MASK BIT(9) -+#define PPE_TB_CFG_AGE_UNBIND_MASK BIT(8) -+#define PPE_TB_CFG_AGE_NON_L4_MASK BIT(7) -+#define PPE_TB_CFG_AGE_PREBIND_MASK BIT(6) -+#define PPE_TB_CFG_SEARCH_MISS_MASK GENMASK(5, 4) -+#define PPE_TB_ENTRY_SIZE_MASK BIT(3) -+#define PPE_DRAM_TB_NUM_ENTRY_MASK GENMASK(2, 0) -+ -+#define REG_PPE_TB_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x220) -+ -+#define REG_PPE_BIND_RATE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x228) -+#define PPE_BIND_RATE_L2B_BIND_MASK GENMASK(31, 16) -+#define PPE_BIND_RATE_BIND_MASK GENMASK(15, 0) -+ -+#define REG_PPE_BIND_LIMIT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x22c) -+#define PPE_BIND_LIMIT0_HALF_MASK GENMASK(29, 16) -+#define PPE_BIND_LIMIT0_QUARTER_MASK GENMASK(13, 0) -+ -+#define REG_PPE_BIND_LIMIT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x230) -+#define PPE_BIND_LIMIT1_NON_L4_MASK GENMASK(23, 16) -+#define PPE_BIND_LIMIT1_FULL_MASK GENMASK(13, 0) -+ -+#define REG_PPE_BND_AGE0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x23c) -+#define PPE_BIND_AGE0_DELTA_NON_L4 GENMASK(30, 16) -+#define PPE_BIND_AGE0_DELTA_UDP GENMASK(14, 0) -+ -+#define REG_PPE_UNBIND_AGE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x238) -+#define PPE_UNBIND_AGE_MIN_PACKETS_MASK GENMASK(31, 16) -+#define PPE_UNBIND_AGE_DELTA_MASK GENMASK(7, 0) -+ -+#define REG_PPE_BND_AGE1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x240) -+#define PPE_BIND_AGE1_DELTA_TCP_FIN GENMASK(30, 16) -+#define PPE_BIND_AGE1_DELTA_TCP GENMASK(14, 0) -+ -+#define REG_PPE_HASH_SEED(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x244) -+#define PPE_HASH_SEED 0x12345678 -+ -+#define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) -+ -+#define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) -+ -+#define REG_PPE_TB_HASH_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x250) -+#define PPE_DRAM_HASH1_MODE_MASK GENMASK(31, 28) -+#define PPE_DRAM_HASH1_EN_MASK BIT(24) -+#define PPE_DRAM_HASH0_MODE_MASK GENMASK(23, 20) -+#define PPE_DRAM_TABLE_EN_MASK BIT(16) -+#define PPE_SRAM_HASH1_MODE_MASK GENMASK(15, 12) -+#define PPE_SRAM_HASH1_EN_MASK BIT(8) -+#define PPE_SRAM_HASH0_MODE_MASK GENMASK(7, 4) -+#define PPE_SRAM_TABLE_EN_MASK BIT(0) -+ -+#define REG_PPE_MTU_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x304) -+#define REG_PPE_MTU(_m, _n) (REG_PPE_MTU_BASE(_m) + ((_n) << 2)) -+#define FP1_EGRESS_MTU_MASK GENMASK(29, 16) -+#define FP0_EGRESS_MTU_MASK GENMASK(13, 0) -+ -+#define REG_PPE_RAM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x31c) -+#define PPE_SRAM_CTRL_ACK_MASK BIT(31) -+#define PPE_SRAM_CTRL_DUAL_SUCESS_MASK BIT(30) -+#define PPE_SRAM_CTRL_ENTRY_MASK GENMASK(23, 8) -+#define PPE_SRAM_WR_DUAL_DIRECTION_MASK BIT(2) -+#define PPE_SRAM_CTRL_WR_MASK BIT(1) -+#define PPE_SRAM_CTRL_REQ_MASK BIT(0) -+ -+#define REG_PPE_RAM_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x320) -+#define REG_PPE_RAM_ENTRY(_m, _n) (REG_PPE_RAM_BASE(_m) + ((_n) << 2)) - - #define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) - #define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) diff --git a/target/linux/airoha/patches-6.12/048-14-v6.15-net-airoha-Add-loopback-support-for-GDM2.patch b/target/linux/airoha/patches-6.12/048-14-v6.15-net-airoha-Add-loopback-support-for-GDM2.patch deleted file mode 100644 index 173900380f9..00000000000 --- a/target/linux/airoha/patches-6.12/048-14-v6.15-net-airoha-Add-loopback-support-for-GDM2.patch +++ /dev/null @@ -1,210 +0,0 @@ -From 9cd451d414f6e29f507a216fb3b19fa68c011f8c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:22 +0100 -Subject: [PATCH 14/15] net: airoha: Add loopback support for GDM2 - -Enable hw redirection for traffic received on GDM2 port to GDM{3,4}. -This is required to apply Qdisc offloading (HTB or ETS) for traffic to -and from GDM{3,4} port. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 71 ++++++++++++++++++++++- - drivers/net/ethernet/airoha/airoha_eth.h | 7 +++ - drivers/net/ethernet/airoha/airoha_ppe.c | 12 ++-- - drivers/net/ethernet/airoha/airoha_regs.h | 29 +++++++++ - 4 files changed, 111 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1609,14 +1609,81 @@ static int airoha_dev_set_macaddr(struct - return 0; - } - -+static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) -+{ -+ u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; -+ struct airoha_eth *eth = port->qdma->eth; -+ u32 chan = port->id == 3 ? 4 : 0; -+ -+ /* Forward the traffic to the proper GDM port */ -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); -+ airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); -+ -+ /* Enable GDM2 loopback */ -+ airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); -+ airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); -+ airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), -+ LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, -+ FIELD_PREP(LPBK_CHAN_MASK, chan) | LPBK_EN_MASK); -+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), -+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -+ FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU)); -+ -+ /* Disable VIP and IFC for GDM2 */ -+ airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); -+ airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); -+ -+ if (port->id == 3) { -+ /* FIXME: handle XSI_PCE1_PORT */ -+ airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), 0x5500); -+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, -+ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, -+ FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); -+ airoha_fe_rmw(eth, -+ REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3), -+ SP_CPORT_PCIE0_MASK, -+ FIELD_PREP(SP_CPORT_PCIE0_MASK, -+ FE_PSE_PORT_CDM2)); -+ } else { -+ /* FIXME: handle XSI_USB_PORT */ -+ airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, -+ FC_ID_OF_SRC_PORT24_MASK, -+ FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); -+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, -+ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, -+ FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT)); -+ airoha_fe_rmw(eth, -+ REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3), -+ SP_CPORT_ETH_MASK, -+ FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2)); -+ } -+} -+ - static int airoha_dev_init(struct net_device *dev) - { - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_eth *eth = port->qdma->eth; -+ u32 pse_port; - - airoha_set_macaddr(port, dev->dev_addr); -- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), -- FE_PSE_PORT_PPE1); -+ -+ switch (port->id) { -+ case 3: -+ case 4: -+ /* If GDM2 is active we can't enable loopback */ -+ if (!eth->ports[1]) -+ airhoha_set_gdm2_loopback(port); -+ fallthrough; -+ case 2: -+ pse_port = FE_PSE_PORT_PPE2; -+ break; -+ default: -+ pse_port = FE_PSE_PORT_PPE1; -+ break; -+ } -+ -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); - - return 0; - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -68,6 +68,13 @@ enum { - }; - - enum { -+ HSGMII_LAN_PCIE0_SRCPORT = 0x16, -+ HSGMII_LAN_PCIE1_SRCPORT, -+ HSGMII_LAN_ETH_SRCPORT, -+ HSGMII_LAN_USB_SRCPORT, -+}; -+ -+enum { - XSI_PCIE0_VIP_PORT_MASK = BIT(22), - XSI_PCIE1_VIP_PORT_MASK = BIT(23), - XSI_USB_VIP_PORT_MASK = BIT(25), ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -216,7 +216,8 @@ static int airoha_ppe_foe_entry_prepare( - AIROHA_FOE_IB1_BIND_TTL; - hwe->ib1 = val; - -- val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); -+ val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f) | -+ AIROHA_FOE_IB2_PSE_QOS; - if (dsa_port >= 0) - val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port); - -@@ -224,14 +225,13 @@ static int airoha_ppe_foe_entry_prepare( - struct airoha_gdm_port *port = netdev_priv(dev); - u8 pse_port; - -- pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; -+ if (dsa_port >= 0) -+ pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; -+ else -+ pse_port = 2; /* uplink relies on GDM2 loopback */ - val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); - } - -- /* FIXME: implement QoS support setting pse_port to 2 (loopback) -- * for uplink and setting qos bit in ib2 -- */ -- - if (is_multicast_ether_addr(data->eth.h_dest)) - val |= AIROHA_FOE_IB2_MULTICAST; - ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -38,6 +38,12 @@ - #define FE_RST_CORE_MASK BIT(0) - - #define REG_FE_FOE_TS 0x0010 -+ -+#define REG_FE_WAN_PORT 0x0024 -+#define WAN1_EN_MASK BIT(16) -+#define WAN1_MASK GENMASK(12, 8) -+#define WAN0_MASK GENMASK(4, 0) -+ - #define REG_FE_WAN_MAC_H 0x0030 - #define REG_FE_LAN_MAC_H 0x0040 - -@@ -126,6 +132,7 @@ - #define GDM_IP4_CKSUM BIT(22) - #define GDM_TCP_CKSUM BIT(21) - #define GDM_UDP_CKSUM BIT(20) -+#define GDM_STRIP_CRC BIT(16) - #define GDM_UCFQ_MASK GENMASK(15, 12) - #define GDM_BCFQ_MASK GENMASK(11, 8) - #define GDM_MCFQ_MASK GENMASK(7, 4) -@@ -139,6 +146,16 @@ - #define GDM_SHORT_LEN_MASK GENMASK(13, 0) - #define GDM_LONG_LEN_MASK GENMASK(29, 16) - -+#define REG_GDM_LPBK_CFG(_n) (GDM_BASE(_n) + 0x1c) -+#define LPBK_GAP_MASK GENMASK(31, 24) -+#define LPBK_LEN_MASK GENMASK(23, 10) -+#define LPBK_CHAN_MASK GENMASK(8, 4) -+#define LPBK_MODE_MASK GENMASK(3, 1) -+#define LPBK_EN_MASK BIT(0) -+ -+#define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) -+#define REG_GDM_RXCHN_EN(_n) (GDM_BASE(_n) + 0x28) -+ - #define REG_FE_CPORT_CFG (GDM1_BASE + 0x40) - #define FE_CPORT_PAD BIT(26) - #define FE_CPORT_PORT_XFC_MASK BIT(25) -@@ -351,6 +368,18 @@ - - #define REG_MC_VLAN_DATA 0x2108 - -+#define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2)) -+#define SP_CPORT_PCIE1_MASK GENMASK(31, 28) -+#define SP_CPORT_PCIE0_MASK GENMASK(27, 24) -+#define SP_CPORT_USB_MASK GENMASK(7, 4) -+#define SP_CPORT_ETH_MASK GENMASK(7, 4) -+ -+#define REG_SRC_PORT_FC_MAP6 0x2298 -+#define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) -+#define FC_ID_OF_SRC_PORT26_MASK GENMASK(20, 16) -+#define FC_ID_OF_SRC_PORT25_MASK GENMASK(12, 8) -+#define FC_ID_OF_SRC_PORT24_MASK GENMASK(4, 0) -+ - #define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 - - /* QDMA */ diff --git a/target/linux/airoha/patches-6.12/048-15-v6.15-net-airoha-Introduce-PPE-debugfs-support.patch b/target/linux/airoha/patches-6.12/048-15-v6.15-net-airoha-Introduce-PPE-debugfs-support.patch deleted file mode 100644 index 50d7fa12668..00000000000 --- a/target/linux/airoha/patches-6.12/048-15-v6.15-net-airoha-Introduce-PPE-debugfs-support.patch +++ /dev/null @@ -1,291 +0,0 @@ -From 3fe15c640f3808c3faf235553c67c867d1389e5c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 28 Feb 2025 11:54:23 +0100 -Subject: [PATCH 15/15] net: airoha: Introduce PPE debugfs support - -Similar to PPE support for Mediatek devices, introduce PPE debugfs -in order to dump binded and unbinded flows. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/Makefile | 1 + - drivers/net/ethernet/airoha/airoha_eth.h | 14 ++ - drivers/net/ethernet/airoha/airoha_ppe.c | 17 +- - .../net/ethernet/airoha/airoha_ppe_debugfs.c | 181 ++++++++++++++++++ - 4 files changed, 209 insertions(+), 4 deletions(-) - create mode 100644 drivers/net/ethernet/airoha/airoha_ppe_debugfs.c - ---- a/drivers/net/ethernet/airoha/Makefile -+++ b/drivers/net/ethernet/airoha/Makefile -@@ -5,4 +5,5 @@ - - obj-$(CONFIG_NET_AIROHA) += airoha-eth.o - airoha-eth-y := airoha_eth.o airoha_ppe.o -+airoha-eth-$(CONFIG_DEBUG_FS) += airoha_ppe_debugfs.o - obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -7,6 +7,7 @@ - #ifndef AIROHA_ETH_H - #define AIROHA_ETH_H - -+#include - #include - #include - #include -@@ -480,6 +481,8 @@ struct airoha_ppe { - - struct hlist_head *foe_flow; - u16 foe_check_time[PPE_NUM_ENTRIES]; -+ -+ struct dentry *debugfs_dir; - }; - - struct airoha_eth { -@@ -533,5 +536,16 @@ int airoha_ppe_setup_tc_block_cb(enum tc - void *cb_priv); - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); -+struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, -+ u32 hash); -+ -+#if CONFIG_DEBUG_FS -+int airoha_ppe_debugfs_init(struct airoha_ppe *ppe); -+#else -+static inline int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) -+{ -+ return 0; -+} -+#endif - - #endif /* AIROHA_ETH_H */ ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -390,8 +390,8 @@ static u32 airoha_ppe_foe_get_entry_hash - return hash; - } - --static struct airoha_foe_entry * --airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, u32 hash) -+struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, -+ u32 hash) - { - if (hash < PPE_SRAM_NUM_ENTRIES) { - u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); -@@ -861,7 +861,7 @@ void airoha_ppe_check_skb(struct airoha_ - int airoha_ppe_init(struct airoha_eth *eth) - { - struct airoha_ppe *ppe; -- int foe_size; -+ int foe_size, err; - - ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); - if (!ppe) -@@ -882,7 +882,15 @@ int airoha_ppe_init(struct airoha_eth *e - if (!ppe->foe_flow) - return -ENOMEM; - -- return rhashtable_init(ð->flow_table, &airoha_flow_table_params); -+ err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); -+ if (err) -+ return err; -+ -+ err = airoha_ppe_debugfs_init(ppe); -+ if (err) -+ rhashtable_destroy(ð->flow_table); -+ -+ return err; - } - - void airoha_ppe_deinit(struct airoha_eth *eth) -@@ -898,4 +906,5 @@ void airoha_ppe_deinit(struct airoha_eth - rcu_read_unlock(); - - rhashtable_destroy(ð->flow_table); -+ debugfs_remove(eth->ppe->debugfs_dir); - } ---- /dev/null -+++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c -@@ -0,0 +1,181 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2025 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#include "airoha_eth.h" -+ -+static void airoha_debugfs_ppe_print_tuple(struct seq_file *m, -+ void *src_addr, void *dest_addr, -+ u16 *src_port, u16 *dest_port, -+ bool ipv6) -+{ -+ __be32 n_addr[IPV6_ADDR_WORDS]; -+ -+ if (ipv6) { -+ ipv6_addr_cpu_to_be32(n_addr, src_addr); -+ seq_printf(m, "%pI6", n_addr); -+ } else { -+ seq_printf(m, "%pI4h", src_addr); -+ } -+ if (src_port) -+ seq_printf(m, ":%d", *src_port); -+ -+ seq_puts(m, "->"); -+ -+ if (ipv6) { -+ ipv6_addr_cpu_to_be32(n_addr, dest_addr); -+ seq_printf(m, "%pI6", n_addr); -+ } else { -+ seq_printf(m, "%pI4h", dest_addr); -+ } -+ if (dest_port) -+ seq_printf(m, ":%d", *dest_port); -+} -+ -+static int airoha_ppe_debugfs_foe_show(struct seq_file *m, void *private, -+ bool bind) -+{ -+ static const char *const ppe_type_str[] = { -+ [PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T", -+ [PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T", -+ [PPE_PKT_TYPE_BRIDGE] = "L2B", -+ [PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE", -+ [PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T", -+ [PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T", -+ [PPE_PKT_TYPE_IPV6_6RD] = "6RD", -+ }; -+ static const char *const ppe_state_str[] = { -+ [AIROHA_FOE_STATE_INVALID] = "INV", -+ [AIROHA_FOE_STATE_UNBIND] = "UNB", -+ [AIROHA_FOE_STATE_BIND] = "BND", -+ [AIROHA_FOE_STATE_FIN] = "FIN", -+ }; -+ struct airoha_ppe *ppe = m->private; -+ int i; -+ -+ for (i = 0; i < PPE_NUM_ENTRIES; i++) { -+ const char *state_str, *type_str = "UNKNOWN"; -+ void *src_addr = NULL, *dest_addr = NULL; -+ u16 *src_port = NULL, *dest_port = NULL; -+ struct airoha_foe_mac_info_common *l2; -+ unsigned char h_source[ETH_ALEN] = {}; -+ unsigned char h_dest[ETH_ALEN]; -+ struct airoha_foe_entry *hwe; -+ u32 type, state, ib2, data; -+ bool ipv6 = false; -+ -+ hwe = airoha_ppe_foe_get_entry(ppe, i); -+ if (!hwe) -+ continue; -+ -+ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); -+ if (!state) -+ continue; -+ -+ if (bind && state != AIROHA_FOE_STATE_BIND) -+ continue; -+ -+ state_str = ppe_state_str[state % ARRAY_SIZE(ppe_state_str)]; -+ type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); -+ if (type < ARRAY_SIZE(ppe_type_str) && ppe_type_str[type]) -+ type_str = ppe_type_str[type]; -+ -+ seq_printf(m, "%05x %s %7s", i, state_str, type_str); -+ -+ switch (type) { -+ case PPE_PKT_TYPE_IPV4_HNAPT: -+ case PPE_PKT_TYPE_IPV4_DSLITE: -+ src_port = &hwe->ipv4.orig_tuple.src_port; -+ dest_port = &hwe->ipv4.orig_tuple.dest_port; -+ fallthrough; -+ case PPE_PKT_TYPE_IPV4_ROUTE: -+ src_addr = &hwe->ipv4.orig_tuple.src_ip; -+ dest_addr = &hwe->ipv4.orig_tuple.dest_ip; -+ break; -+ case PPE_PKT_TYPE_IPV6_ROUTE_5T: -+ src_port = &hwe->ipv6.src_port; -+ dest_port = &hwe->ipv6.dest_port; -+ fallthrough; -+ case PPE_PKT_TYPE_IPV6_ROUTE_3T: -+ case PPE_PKT_TYPE_IPV6_6RD: -+ src_addr = &hwe->ipv6.src_ip; -+ dest_addr = &hwe->ipv6.dest_ip; -+ ipv6 = true; -+ break; -+ default: -+ break; -+ } -+ -+ if (src_addr && dest_addr) { -+ seq_puts(m, " orig="); -+ airoha_debugfs_ppe_print_tuple(m, src_addr, dest_addr, -+ src_port, dest_port, ipv6); -+ } -+ -+ switch (type) { -+ case PPE_PKT_TYPE_IPV4_HNAPT: -+ case PPE_PKT_TYPE_IPV4_DSLITE: -+ src_port = &hwe->ipv4.new_tuple.src_port; -+ dest_port = &hwe->ipv4.new_tuple.dest_port; -+ fallthrough; -+ case PPE_PKT_TYPE_IPV4_ROUTE: -+ src_addr = &hwe->ipv4.new_tuple.src_ip; -+ dest_addr = &hwe->ipv4.new_tuple.dest_ip; -+ seq_puts(m, " new="); -+ airoha_debugfs_ppe_print_tuple(m, src_addr, dest_addr, -+ src_port, dest_port, -+ ipv6); -+ break; -+ default: -+ break; -+ } -+ -+ if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { -+ data = hwe->ipv6.data; -+ ib2 = hwe->ipv6.ib2; -+ l2 = &hwe->ipv6.l2; -+ } else { -+ data = hwe->ipv4.data; -+ ib2 = hwe->ipv4.ib2; -+ l2 = &hwe->ipv4.l2.common; -+ *((__be16 *)&h_source[4]) = -+ cpu_to_be16(hwe->ipv4.l2.src_mac_lo); -+ } -+ -+ *((__be32 *)h_dest) = cpu_to_be32(l2->dest_mac_hi); -+ *((__be16 *)&h_dest[4]) = cpu_to_be16(l2->dest_mac_lo); -+ *((__be32 *)h_source) = cpu_to_be32(l2->src_mac_hi); -+ -+ seq_printf(m, " eth=%pM->%pM etype=%04x data=%08x" -+ " vlan=%d,%d ib1=%08x ib2=%08x\n", -+ h_source, h_dest, l2->etype, data, -+ l2->vlan1, l2->vlan2, hwe->ib1, ib2); -+ } -+ -+ return 0; -+} -+ -+static int airoha_ppe_debugfs_foe_all_show(struct seq_file *m, void *private) -+{ -+ return airoha_ppe_debugfs_foe_show(m, private, false); -+} -+DEFINE_SHOW_ATTRIBUTE(airoha_ppe_debugfs_foe_all); -+ -+static int airoha_ppe_debugfs_foe_bind_show(struct seq_file *m, void *private) -+{ -+ return airoha_ppe_debugfs_foe_show(m, private, true); -+} -+DEFINE_SHOW_ATTRIBUTE(airoha_ppe_debugfs_foe_bind); -+ -+int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) -+{ -+ ppe->debugfs_dir = debugfs_create_dir("ppe", NULL); -+ debugfs_create_file("entries", 0444, ppe->debugfs_dir, ppe, -+ &airoha_ppe_debugfs_foe_all_fops); -+ debugfs_create_file("bind", 0444, ppe->debugfs_dir, ppe, -+ &airoha_ppe_debugfs_foe_bind_fops); -+ -+ return 0; -+} diff --git a/target/linux/airoha/patches-6.12/049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch b/target/linux/airoha/patches-6.12/049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch deleted file mode 100644 index ea68cab33e7..00000000000 --- a/target/linux/airoha/patches-6.12/049-01-v6.16-thermal-drivers-Add-support-for-Airoha-EN7581-therma.patch +++ /dev/null @@ -1,550 +0,0 @@ -From 42de37f40e1bc818df216dfa0918c114cfb5941d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 11 May 2025 20:49:55 +0200 -Subject: [PATCH] thermal/drivers: Add support for Airoha EN7581 thermal sensor - -Add support for Airoha EN7581 thermal sensor. This provide support for -reading the CPU or SoC Package sensor and to setup trip points for hot -and critical condition. An interrupt is fired to react on this and -doesn't require passive poll to read the temperature. - -The thermal regs provide a way to read the ADC value from an external -register placed in the Chip SCU regs. Monitor will read this value and -fire an interrupt if the trip condition configured is reached. - -The Thermal Trip and Interrupt logic is conceptually similar to Mediatek -LVTS Thermal but differ in register mapping and actual function/bug -workaround. The implementation only share some register names but from -functionality observation it's very different and used only for the -basic function of periodically poll the temp and trip the interrupt. - -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20250511185003.3754495-2-ansuelsmth@gmail.com -Signed-off-by: Daniel Lezcano ---- - drivers/thermal/Kconfig | 9 + - drivers/thermal/Makefile | 1 + - drivers/thermal/airoha_thermal.c | 489 +++++++++++++++++++++++++++++++ - 3 files changed, 499 insertions(+) - create mode 100644 drivers/thermal/airoha_thermal.c - ---- a/drivers/thermal/Kconfig -+++ b/drivers/thermal/Kconfig -@@ -318,6 +318,15 @@ config QORIQ_THERMAL - cpufreq is used as the cooling device to throttle CPUs when the - passive trip is crossed. - -+config AIROHA_THERMAL -+ tristate "Airoha thermal sensor driver" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ depends on MFD_SYSCON -+ depends on OF -+ help -+ Enable this to plug the Airoha thermal sensor driver into the Linux -+ thermal framework. -+ - config SPEAR_THERMAL - tristate "SPEAr thermal sensor driver" - depends on PLAT_SPEAR || COMPILE_TEST ---- a/drivers/thermal/Makefile -+++ b/drivers/thermal/Makefile -@@ -35,6 +35,7 @@ obj-$(CONFIG_K3_THERMAL) += k3_bandgap.o - # platform thermal drivers - obj-y += broadcom/ - obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o -+obj-$(CONFIG_AIROHA_THERMAL) += airoha_thermal.o - obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o - obj-$(CONFIG_SUN8I_THERMAL) += sun8i_thermal.o - obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o ---- /dev/null -+++ b/drivers/thermal/airoha_thermal.c -@@ -0,0 +1,489 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* SCU regs */ -+#define EN7581_PLLRG_PROTECT 0x268 -+#define EN7581_PWD_TADC 0x2ec -+#define EN7581_MUX_TADC GENMASK(3, 1) -+#define EN7581_DOUT_TADC 0x2f8 -+#define EN7581_DOUT_TADC_MASK GENMASK(15, 0) -+ -+/* PTP_THERMAL regs */ -+#define EN7581_TEMPMONCTL0 0x800 -+#define EN7581_SENSE3_EN BIT(3) -+#define EN7581_SENSE2_EN BIT(2) -+#define EN7581_SENSE1_EN BIT(1) -+#define EN7581_SENSE0_EN BIT(0) -+#define EN7581_TEMPMONCTL1 0x804 -+/* period unit calculated in BUS clock * 256 scaling-up */ -+#define EN7581_PERIOD_UNIT GENMASK(9, 0) -+#define EN7581_TEMPMONCTL2 0x808 -+#define EN7581_FILT_INTERVAL GENMASK(25, 16) -+#define EN7581_SEN_INTERVAL GENMASK(9, 0) -+#define EN7581_TEMPMONINT 0x80C -+#define EN7581_STAGE3_INT_EN BIT(31) -+#define EN7581_STAGE2_INT_EN BIT(30) -+#define EN7581_STAGE1_INT_EN BIT(29) -+#define EN7581_FILTER_INT_EN_3 BIT(28) -+#define EN7581_IMMD_INT_EN3 BIT(27) -+#define EN7581_NOHOTINTEN3 BIT(26) -+#define EN7581_HOFSINTEN3 BIT(25) -+#define EN7581_LOFSINTEN3 BIT(24) -+#define EN7581_HINTEN3 BIT(23) -+#define EN7581_CINTEN3 BIT(22) -+#define EN7581_FILTER_INT_EN_2 BIT(21) -+#define EN7581_FILTER_INT_EN_1 BIT(20) -+#define EN7581_FILTER_INT_EN_0 BIT(19) -+#define EN7581_IMMD_INT_EN2 BIT(18) -+#define EN7581_IMMD_INT_EN1 BIT(17) -+#define EN7581_IMMD_INT_EN0 BIT(16) -+#define EN7581_TIME_OUT_INT_EN BIT(15) -+#define EN7581_NOHOTINTEN2 BIT(14) -+#define EN7581_HOFSINTEN2 BIT(13) -+#define EN7581_LOFSINTEN2 BIT(12) -+#define EN7581_HINTEN2 BIT(11) -+#define EN7581_CINTEN2 BIT(10) -+#define EN7581_NOHOTINTEN1 BIT(9) -+#define EN7581_HOFSINTEN1 BIT(8) -+#define EN7581_LOFSINTEN1 BIT(7) -+#define EN7581_HINTEN1 BIT(6) -+#define EN7581_CINTEN1 BIT(5) -+#define EN7581_NOHOTINTEN0 BIT(4) -+/* Similar to COLD and HOT also these seems to be swapped in documentation */ -+#define EN7581_LOFSINTEN0 BIT(3) /* In documentation: BIT(2) */ -+#define EN7581_HOFSINTEN0 BIT(2) /* In documentation: BIT(3) */ -+/* It seems documentation have these swapped as the HW -+ * - Fire BIT(1) when lower than EN7581_COLD_THRE -+ * - Fire BIT(0) and BIT(5) when higher than EN7581_HOT2NORMAL_THRE or -+ * EN7581_HOT_THRE -+ */ -+#define EN7581_CINTEN0 BIT(1) /* In documentation: BIT(0) */ -+#define EN7581_HINTEN0 BIT(0) /* In documentation: BIT(1) */ -+#define EN7581_TEMPMONINTSTS 0x810 -+#define EN7581_STAGE3_INT_STAT BIT(31) -+#define EN7581_STAGE2_INT_STAT BIT(30) -+#define EN7581_STAGE1_INT_STAT BIT(29) -+#define EN7581_FILTER_INT_STAT_3 BIT(28) -+#define EN7581_IMMD_INT_STS3 BIT(27) -+#define EN7581_NOHOTINTSTS3 BIT(26) -+#define EN7581_HOFSINTSTS3 BIT(25) -+#define EN7581_LOFSINTSTS3 BIT(24) -+#define EN7581_HINTSTS3 BIT(23) -+#define EN7581_CINTSTS3 BIT(22) -+#define EN7581_FILTER_INT_STAT_2 BIT(21) -+#define EN7581_FILTER_INT_STAT_1 BIT(20) -+#define EN7581_FILTER_INT_STAT_0 BIT(19) -+#define EN7581_IMMD_INT_STS2 BIT(18) -+#define EN7581_IMMD_INT_STS1 BIT(17) -+#define EN7581_IMMD_INT_STS0 BIT(16) -+#define EN7581_TIME_OUT_INT_STAT BIT(15) -+#define EN7581_NOHOTINTSTS2 BIT(14) -+#define EN7581_HOFSINTSTS2 BIT(13) -+#define EN7581_LOFSINTSTS2 BIT(12) -+#define EN7581_HINTSTS2 BIT(11) -+#define EN7581_CINTSTS2 BIT(10) -+#define EN7581_NOHOTINTSTS1 BIT(9) -+#define EN7581_HOFSINTSTS1 BIT(8) -+#define EN7581_LOFSINTSTS1 BIT(7) -+#define EN7581_HINTSTS1 BIT(6) -+#define EN7581_CINTSTS1 BIT(5) -+#define EN7581_NOHOTINTSTS0 BIT(4) -+/* Similar to COLD and HOT also these seems to be swapped in documentation */ -+#define EN7581_LOFSINTSTS0 BIT(3) /* In documentation: BIT(2) */ -+#define EN7581_HOFSINTSTS0 BIT(2) /* In documentation: BIT(3) */ -+/* It seems documentation have these swapped as the HW -+ * - Fire BIT(1) when lower than EN7581_COLD_THRE -+ * - Fire BIT(0) and BIT(5) when higher than EN7581_HOT2NORMAL_THRE or -+ * EN7581_HOT_THRE -+ * -+ * To clear things, we swap the define but we keep them documented here. -+ */ -+#define EN7581_CINTSTS0 BIT(1) /* In documentation: BIT(0) */ -+#define EN7581_HINTSTS0 BIT(0) /* In documentation: BIT(1)*/ -+/* Monitor will take the bigger threshold between HOT2NORMAL and HOT -+ * and will fire both HOT2NORMAL and HOT interrupt when higher than the 2 -+ * -+ * It has also been observed that not setting HOT2NORMAL makes the monitor -+ * treat COLD threshold as HOT2NORMAL. -+ */ -+#define EN7581_TEMPH2NTHRE 0x824 -+/* It seems HOT2NORMAL is actually NORMAL2HOT */ -+#define EN7581_HOT2NORMAL_THRE GENMASK(11, 0) -+#define EN7581_TEMPHTHRE 0x828 -+#define EN7581_HOT_THRE GENMASK(11, 0) -+/* Monitor will use this as HOT2NORMAL (fire interrupt when lower than...)*/ -+#define EN7581_TEMPCTHRE 0x82c -+#define EN7581_COLD_THRE GENMASK(11, 0) -+/* Also LOW and HIGH offset register are swapped */ -+#define EN7581_TEMPOFFSETL 0x830 /* In documentation: 0x834 */ -+#define EN7581_LOW_OFFSET GENMASK(11, 0) -+#define EN7581_TEMPOFFSETH 0x834 /* In documentation: 0x830 */ -+#define EN7581_HIGH_OFFSET GENMASK(11, 0) -+#define EN7581_TEMPMSRCTL0 0x838 -+#define EN7581_MSRCTL3 GENMASK(11, 9) -+#define EN7581_MSRCTL2 GENMASK(8, 6) -+#define EN7581_MSRCTL1 GENMASK(5, 3) -+#define EN7581_MSRCTL0 GENMASK(2, 0) -+#define EN7581_TEMPADCVALIDADDR 0x878 -+#define EN7581_ADC_VALID_ADDR GENMASK(31, 0) -+#define EN7581_TEMPADCVOLTADDR 0x87c -+#define EN7581_ADC_VOLT_ADDR GENMASK(31, 0) -+#define EN7581_TEMPRDCTRL 0x880 -+/* -+ * NOTICE: AHB have this set to 0 by default. Means that -+ * the same addr is used for ADC volt and valid reading. -+ * In such case, VALID ADDR is used and volt addr is ignored. -+ */ -+#define EN7581_RD_CTRL_DIFF BIT(0) -+#define EN7581_TEMPADCVALIDMASK 0x884 -+#define EN7581_ADV_RD_VALID_POLARITY BIT(5) -+#define EN7581_ADV_RD_VALID_POS GENMASK(4, 0) -+#define EN7581_TEMPADCVOLTAGESHIFT 0x888 -+#define EN7581_ADC_VOLTAGE_SHIFT GENMASK(4, 0) -+/* -+ * Same values for each CTL. -+ * Can operate in: -+ * - 1 sample -+ * - 2 sample and make average of them -+ * - 4,6,10,16 sample, drop max and min and make avgerage of them -+ */ -+#define EN7581_MSRCTL_1SAMPLE 0x0 -+#define EN7581_MSRCTL_AVG2SAMPLE 0x1 -+#define EN7581_MSRCTL_4SAMPLE_MAX_MIX_AVG2 0x2 -+#define EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4 0x3 -+#define EN7581_MSRCTL_10SAMPLE_MAX_MIX_AVG8 0x4 -+#define EN7581_MSRCTL_18SAMPLE_MAX_MIX_AVG16 0x5 -+#define EN7581_TEMPAHBPOLL 0x840 -+#define EN7581_ADC_POLL_INTVL GENMASK(31, 0) -+/* PTPSPARE0,2 reg are used to store efuse info for calibrated temp offset */ -+#define EN7581_EFUSE_TEMP_OFFSET_REG 0xf20 /* PTPSPARE0 */ -+#define EN7581_EFUSE_TEMP_OFFSET GENMASK(31, 16) -+#define EN7581_PTPSPARE1 0xf24 /* PTPSPARE1 */ -+#define EN7581_EFUSE_TEMP_CPU_SENSOR_REG 0xf28 /* PTPSPARE2 */ -+ -+#define EN7581_SLOPE_X100_DIO_DEFAULT 5645 -+#define EN7581_SLOPE_X100_DIO_AVS 5645 -+ -+#define EN7581_INIT_TEMP_CPK_X10 300 -+#define EN7581_INIT_TEMP_FTK_X10 620 -+#define EN7581_INIT_TEMP_NONK_X10 550 -+ -+#define EN7581_SCU_THERMAL_PROTECT_KEY 0x12 -+#define EN7581_SCU_THERMAL_MUX_DIODE1 0x7 -+ -+/* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */ -+#define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \ -+ (priv)->default_slope) / 1000) + \ -+ (priv)->default_offset) -+ -+/* Convert raw to temp ((((temp - offset) * 1000) / slope + init) * 100) */ -+#define RAW_TO_TEMP(priv, raw) (((((raw) - (priv)->default_offset) * 1000) / \ -+ (priv)->default_slope + \ -+ (priv)->init_temp) * 100) -+ -+#define AIROHA_MAX_SAMPLES 6 -+ -+struct airoha_thermal_priv { -+ void __iomem *base; -+ struct regmap *chip_scu; -+ struct resource scu_adc_res; -+ -+ struct thermal_zone_device *tz; -+ int init_temp; -+ int default_slope; -+ int default_offset; -+}; -+ -+static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv) -+{ -+ u32 val; -+ -+ regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val); -+ return FIELD_GET(EN7581_DOUT_TADC_MASK, val); -+} -+ -+static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv) -+{ -+ u32 adc_mux, pllrg; -+ -+ /* Save PLLRG current value */ -+ regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg); -+ -+ /* Give access to thermal regs */ -+ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY); -+ adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1); -+ regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux); -+ -+ /* Restore PLLRG value on exit */ -+ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg); -+} -+ -+static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp) -+{ -+ struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); -+ int min_value, max_value, avg_value, value; -+ int i; -+ -+ avg_value = 0; -+ min_value = INT_MAX; -+ max_value = INT_MIN; -+ -+ for (i = 0; i < AIROHA_MAX_SAMPLES; i++) { -+ value = airoha_get_thermal_ADC(priv); -+ min_value = min(value, min_value); -+ max_value = max(value, max_value); -+ avg_value += value; -+ } -+ -+ /* Drop min and max and average for the remaining sample */ -+ avg_value -= (min_value + max_value); -+ avg_value /= AIROHA_MAX_SAMPLES - 2; -+ -+ *temp = RAW_TO_TEMP(priv, avg_value); -+ return 0; -+} -+ -+static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low, -+ int high) -+{ -+ struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); -+ bool enable_monitor = false; -+ -+ if (high != INT_MAX) { -+ /* Validate high and clamp it a supported value */ -+ high = clamp_t(int, high, RAW_TO_TEMP(priv, 0), -+ RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); -+ -+ /* We offset the high temp of 1°C to trigger correct event */ -+ writel(TEMP_TO_RAW(priv, high) >> 4, -+ priv->base + EN7581_TEMPOFFSETH); -+ -+ enable_monitor = true; -+ } -+ -+ if (low != -INT_MAX) { -+ /* Validate low and clamp it to a supported value */ -+ low = clamp_t(int, high, RAW_TO_TEMP(priv, 0), -+ RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); -+ -+ /* We offset the low temp of 1°C to trigger correct event */ -+ writel(TEMP_TO_RAW(priv, low) >> 4, -+ priv->base + EN7581_TEMPOFFSETL); -+ -+ enable_monitor = true; -+ } -+ -+ /* Enable sensor 0 monitor after trip are set */ -+ if (enable_monitor) -+ writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0); -+ -+ return 0; -+} -+ -+static const struct thermal_zone_device_ops thdev_ops = { -+ .get_temp = airoha_thermal_get_temp, -+ .set_trips = airoha_thermal_set_trips, -+}; -+ -+static irqreturn_t airoha_thermal_irq(int irq, void *data) -+{ -+ struct airoha_thermal_priv *priv = data; -+ enum thermal_notify_event event; -+ bool update = false; -+ u32 status; -+ -+ status = readl(priv->base + EN7581_TEMPMONINTSTS); -+ switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) { -+ case EN7581_HOFSINTSTS0: -+ event = THERMAL_TRIP_VIOLATED; -+ update = true; -+ break; -+ case EN7581_LOFSINTSTS0: -+ event = THERMAL_EVENT_UNSPECIFIED; -+ update = true; -+ break; -+ default: -+ /* Should be impossible as we enable only these Interrupt */ -+ break; -+ } -+ -+ /* Reset Interrupt */ -+ writel(status, priv->base + EN7581_TEMPMONINTSTS); -+ -+ if (update) -+ thermal_zone_device_update(priv->tz, event); -+ -+ return IRQ_HANDLED; -+} -+ -+static void airoha_thermal_setup_adc_val(struct device *dev, -+ struct airoha_thermal_priv *priv) -+{ -+ u32 efuse_calib_info, cpu_sensor; -+ -+ /* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */ -+ airoha_init_thermal_ADC_mode(priv); -+ /* sleep 10 ms for ADC to enable */ -+ usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); -+ -+ efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG); -+ if (efuse_calib_info) { -+ priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info); -+ /* Different slope are applied if the sensor is used for CPU or for package */ -+ cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG); -+ if (cpu_sensor) { -+ priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT; -+ priv->init_temp = EN7581_INIT_TEMP_FTK_X10; -+ } else { -+ priv->default_slope = EN7581_SLOPE_X100_DIO_AVS; -+ priv->init_temp = EN7581_INIT_TEMP_CPK_X10; -+ } -+ } else { -+ priv->default_offset = airoha_get_thermal_ADC(priv); -+ priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT; -+ priv->init_temp = EN7581_INIT_TEMP_NONK_X10; -+ dev_info(dev, "missing thermal calibrarion EFUSE, using non calibrated value\n"); -+ } -+} -+ -+static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) -+{ -+ /* Set measure mode */ -+ writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4), -+ priv->base + EN7581_TEMPMSRCTL0); -+ -+ /* -+ * Configure ADC valid reading addr -+ * The AHB temp monitor system doesn't have direct access to the -+ * thermal sensor. It does instead work by providing all kind of -+ * address to configure how to access and setup an ADC for the -+ * sensor. EN7581 supports only one sensor hence the -+ * implementation is greatly simplified but the AHB supports -+ * up to 4 different sensor from the same ADC that can be -+ * switched by tuning the ADC mux or wiriting address. -+ * -+ * We set valid instead of volt as we don't enable valid/volt -+ * split reading and AHB read valid addr in such case. -+ */ -+ writel(priv->scu_adc_res.start + EN7581_DOUT_TADC, -+ priv->base + EN7581_TEMPADCVALIDADDR); -+ -+ /* -+ * Configure valid bit on a fake value of bit 16. The ADC outputs -+ * max of 2 bytes for voltage. -+ */ -+ writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16), -+ priv->base + EN7581_TEMPADCVALIDMASK); -+ -+ /* -+ * AHB supports max 12 bytes for ADC voltage. Shift the read -+ * value 4 bit to the right. Precision lost by this is minimal -+ * in the order of half a °C and is acceptable in the context -+ * of triggering interrupt in critical condition. -+ */ -+ writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4), -+ priv->base + EN7581_TEMPADCVOLTAGESHIFT); -+ -+ /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */ -+ writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3), -+ priv->base + EN7581_TEMPMONCTL1); -+ -+ /* -+ * filt interval is 1 * 52.715us = 52.715us, -+ * sen interval is 379 * 52.715us = 19.97ms -+ */ -+ writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) | -+ FIELD_PREP(EN7581_FILT_INTERVAL, 379), -+ priv->base + EN7581_TEMPMONCTL2); -+ -+ /* AHB poll is set to 146 * 68.64 = 10.02us */ -+ writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146), -+ priv->base + EN7581_TEMPAHBPOLL); -+} -+ -+static int airoha_thermal_probe(struct platform_device *pdev) -+{ -+ struct airoha_thermal_priv *priv; -+ struct device_node *chip_scu_np; -+ struct device *dev = &pdev->dev; -+ int irq, ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(priv->base)) -+ return PTR_ERR(priv->base); -+ -+ chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0); -+ if (!chip_scu_np) -+ return -EINVAL; -+ -+ priv->chip_scu = syscon_node_to_regmap(chip_scu_np); -+ if (IS_ERR(priv->chip_scu)) -+ return PTR_ERR(priv->chip_scu); -+ -+ of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res); -+ of_node_put(chip_scu_np); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+ -+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -+ airoha_thermal_irq, IRQF_ONESHOT, -+ pdev->name, priv); -+ if (ret) { -+ dev_err(dev, "Can't get interrupt working.\n"); -+ return ret; -+ } -+ -+ airoha_thermal_setup_monitor(priv); -+ airoha_thermal_setup_adc_val(dev, priv); -+ -+ /* register of thermal sensor and get info from DT */ -+ priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops); -+ if (IS_ERR(priv->tz)) { -+ dev_err(dev, "register thermal zone sensor failed\n"); -+ return PTR_ERR(priv->tz); -+ } -+ -+ platform_set_drvdata(pdev, priv); -+ -+ /* Enable LOW and HIGH interrupt */ -+ writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0, -+ priv->base + EN7581_TEMPMONINT); -+ -+ return 0; -+} -+ -+static const struct of_device_id airoha_thermal_match[] = { -+ { .compatible = "airoha,en7581-thermal" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, airoha_thermal_match); -+ -+static struct platform_driver airoha_thermal_driver = { -+ .driver = { -+ .name = "airoha-thermal", -+ .of_match_table = airoha_thermal_match, -+ }, -+ .probe = airoha_thermal_probe, -+}; -+ -+module_platform_driver(airoha_thermal_driver); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Airoha thermal driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch b/target/linux/airoha/patches-6.12/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch deleted file mode 100644 index 7b1b9478c37..00000000000 --- a/target/linux/airoha/patches-6.12/049-02-v6.16-thermal-drivers-airoha-Fix-spelling-mistake.patch +++ /dev/null @@ -1,44 +0,0 @@ -From e23cba0ab49a9cf95e9bc3a86cfbf336b0e285f6 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 14 May 2025 23:39:12 +0200 -Subject: [PATCH] thermal/drivers/airoha: Fix spelling mistake - -Fix various spelling mistake in airoha_thermal_setup_monitor() and -define. - -Reported-by: Alok Tiwari -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20250514213919.2321490-1-ansuelsmth@gmail.com -Signed-off-by: Daniel Lezcano ---- - drivers/thermal/airoha_thermal.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/thermal/airoha_thermal.c -+++ b/drivers/thermal/airoha_thermal.c -@@ -155,7 +155,7 @@ - * Can operate in: - * - 1 sample - * - 2 sample and make average of them -- * - 4,6,10,16 sample, drop max and min and make avgerage of them -+ * - 4,6,10,16 sample, drop max and min and make average of them - */ - #define EN7581_MSRCTL_1SAMPLE 0x0 - #define EN7581_MSRCTL_AVG2SAMPLE 0x1 -@@ -365,12 +365,12 @@ static void airoha_thermal_setup_monitor - /* - * Configure ADC valid reading addr - * The AHB temp monitor system doesn't have direct access to the -- * thermal sensor. It does instead work by providing all kind of -- * address to configure how to access and setup an ADC for the -+ * thermal sensor. It does instead work by providing various -+ * addresses to configure how to access and setup an ADC for the - * sensor. EN7581 supports only one sensor hence the - * implementation is greatly simplified but the AHB supports -- * up to 4 different sensor from the same ADC that can be -- * switched by tuning the ADC mux or wiriting address. -+ * up to 4 different sensors from the same ADC that can be -+ * switched by tuning the ADC mux or writing address. - * - * We set valid instead of volt as we don't enable valid/volt - * split reading and AHB read valid addr in such case. diff --git a/target/linux/airoha/patches-6.12/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch b/target/linux/airoha/patches-6.12/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch deleted file mode 100644 index 15bbee2a240..00000000000 --- a/target/linux/airoha/patches-6.12/051-v6.15-pinctrl-airoha-fix-wrong-PHY-LED-mapping-and-PHY2-LE.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 457d9772e8a5cdae64f66b5f7d5b0247365191ec Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 1 Apr 2025 15:50:21 +0200 -Subject: [PATCH] pinctrl: airoha: fix wrong PHY LED mapping and PHY2 LED - defines - -The current PHY2 LED define are wrong and actually set BITs outside the -related mask. Fix it and set the correct value. While at it, also use -FIELD_PREP_CONST macro to make it simple to understand what values are -actually applied for the mask. - -Also fix wrong PHY LED mapping. The SoC Switch supports up to 4 port but -the register define mapping for 5 PHY port, starting from 0. The mapping -was wrongly defined starting from PHY1. Reorder the function group to -start from PHY0. PHY4 is actually never supported as we don't have a -GPIO pin to assign. - -Cc: stable@vger.kernel.org -Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") -Reviewed-by: Benjamin Larsson -Signed-off-by: Christian Marangi -Acked-by: Lorenzo Bianconi -Link: https://lore.kernel.org/20250401135026.18018-1-ansuelsmth@gmail.com -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 159 ++++++++++------------ - 1 file changed, 70 insertions(+), 89 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -6,6 +6,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -112,39 +113,19 @@ - #define REG_LAN_LED1_MAPPING 0x0280 - - #define LAN4_LED_MAPPING_MASK GENMASK(18, 16) --#define LAN4_PHY4_LED_MAP BIT(18) --#define LAN4_PHY2_LED_MAP BIT(17) --#define LAN4_PHY1_LED_MAP BIT(16) --#define LAN4_PHY0_LED_MAP 0 --#define LAN4_PHY3_LED_MAP GENMASK(17, 16) -+#define LAN4_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN4_LED_MAPPING_MASK, (_n)) - - #define LAN3_LED_MAPPING_MASK GENMASK(14, 12) --#define LAN3_PHY4_LED_MAP BIT(14) --#define LAN3_PHY2_LED_MAP BIT(13) --#define LAN3_PHY1_LED_MAP BIT(12) --#define LAN3_PHY0_LED_MAP 0 --#define LAN3_PHY3_LED_MAP GENMASK(13, 12) -+#define LAN3_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n)) - - #define LAN2_LED_MAPPING_MASK GENMASK(10, 8) --#define LAN2_PHY4_LED_MAP BIT(12) --#define LAN2_PHY2_LED_MAP BIT(11) --#define LAN2_PHY1_LED_MAP BIT(10) --#define LAN2_PHY0_LED_MAP 0 --#define LAN2_PHY3_LED_MAP GENMASK(11, 10) -+#define LAN2_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n)) - - #define LAN1_LED_MAPPING_MASK GENMASK(6, 4) --#define LAN1_PHY4_LED_MAP BIT(6) --#define LAN1_PHY2_LED_MAP BIT(5) --#define LAN1_PHY1_LED_MAP BIT(4) --#define LAN1_PHY0_LED_MAP 0 --#define LAN1_PHY3_LED_MAP GENMASK(5, 4) -+#define LAN1_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n)) - - #define LAN0_LED_MAPPING_MASK GENMASK(2, 0) --#define LAN0_PHY4_LED_MAP BIT(3) --#define LAN0_PHY2_LED_MAP BIT(2) --#define LAN0_PHY1_LED_MAP BIT(1) --#define LAN0_PHY0_LED_MAP 0 --#define LAN0_PHY3_LED_MAP GENMASK(2, 1) -+#define LAN0_PHY_LED_MAP(_n) FIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n)) - - /* CONF */ - #define REG_I2C_SDA_E2 0x001c -@@ -1476,8 +1457,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY1_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, { -@@ -1491,8 +1472,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY1_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, { -@@ -1506,8 +1487,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY1_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, { -@@ -1521,8 +1502,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY1_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, -@@ -1540,8 +1521,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY2_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, { -@@ -1555,8 +1536,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY2_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, { -@@ -1570,8 +1551,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY2_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, { -@@ -1585,8 +1566,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY2_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, -@@ -1604,8 +1585,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY3_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, { -@@ -1619,8 +1600,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY3_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, { -@@ -1634,8 +1615,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY3_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, { -@@ -1649,8 +1630,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY3_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, -@@ -1668,8 +1649,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY4_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, { -@@ -1683,8 +1664,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY4_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, { -@@ -1698,8 +1679,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY4_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, { -@@ -1713,8 +1694,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED0_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY4_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, -@@ -1732,8 +1713,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY1_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, { -@@ -1747,8 +1728,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY1_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, { -@@ -1762,8 +1743,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY1_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, { -@@ -1777,8 +1758,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY1_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(0) - }, - .regmap_size = 2, - }, -@@ -1796,8 +1777,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY2_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, { -@@ -1811,8 +1792,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY2_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, { -@@ -1826,8 +1807,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY2_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, { -@@ -1841,8 +1822,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY2_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(1) - }, - .regmap_size = 2, - }, -@@ -1860,8 +1841,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY3_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, { -@@ -1875,8 +1856,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY3_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, { -@@ -1890,8 +1871,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY3_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, { -@@ -1905,8 +1886,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY3_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(2) - }, - .regmap_size = 2, - }, -@@ -1924,8 +1905,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY4_LED_MAP -+ LAN0_LED_MAPPING_MASK, -+ LAN0_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, { -@@ -1939,8 +1920,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY4_LED_MAP -+ LAN1_LED_MAPPING_MASK, -+ LAN1_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, { -@@ -1954,8 +1935,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY4_LED_MAP -+ LAN2_LED_MAPPING_MASK, -+ LAN2_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, { -@@ -1969,8 +1950,8 @@ static const struct airoha_pinctrl_func_ - .regmap[1] = { - AIROHA_FUNC_MUX, - REG_LAN_LED1_MAPPING, -- LAN4_LED_MAPPING_MASK, -- LAN4_PHY4_LED_MAP -+ LAN3_LED_MAPPING_MASK, -+ LAN3_PHY_LED_MAP(3) - }, - .regmap_size = 2, - }, diff --git a/target/linux/airoha/patches-6.12/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch b/target/linux/airoha/patches-6.12/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch deleted file mode 100644 index 904c424187b..00000000000 --- a/target/linux/airoha/patches-6.12/063-01-v6.15-net-airoha-Move-min-max-packet-len-configuration-in-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 54d989d58d2ac87c8504c2306ba8b4957c60e8dc Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 4 Mar 2025 15:21:08 +0100 -Subject: [PATCH 1/6] net: airoha: Move min/max packet len configuration in - airoha_dev_open() - -In order to align max allowed packet size to the configured mtu, move -REG_GDM_LEN_CFG configuration in airoha_dev_open routine. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-1-283ebc61120e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -138,15 +138,10 @@ static void airoha_fe_maccr_init(struct - { - int p; - -- for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) { -+ for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) - airoha_fe_set(eth, REG_GDM_FWD_CFG(p), - GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | - GDM_DROP_CRC_ERR); -- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), -- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -- FIELD_PREP(GDM_LONG_LEN_MASK, 4004)); -- } - - airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, - FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); -@@ -1541,9 +1536,9 @@ static void airoha_update_hw_stats(struc - - static int airoha_dev_open(struct net_device *dev) - { -+ int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN; - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_qdma *qdma = port->qdma; -- int err; - - netif_tx_start_all_queues(dev); - err = airoha_set_vip_for_gdm_port(port, true); -@@ -1557,6 +1552,11 @@ static int airoha_dev_open(struct net_de - airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), - GDM_STAG_EN_MASK); - -+ airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id), -+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -+ FIELD_PREP(GDM_LONG_LEN_MASK, len)); -+ - airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, - GLOBAL_CFG_TX_DMA_EN_MASK | - GLOBAL_CFG_RX_DMA_EN_MASK); diff --git a/target/linux/airoha/patches-6.12/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch b/target/linux/airoha/patches-6.12/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch deleted file mode 100644 index 87c180f0732..00000000000 --- a/target/linux/airoha/patches-6.12/063-02-v6.15-net-airoha-Enable-Rx-Scatter-Gather.patch +++ /dev/null @@ -1,170 +0,0 @@ -From e12182ddb6e712951d21a50e2c8ccd700e41a40c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 4 Mar 2025 15:21:09 +0100 -Subject: [PATCH 2/6] net: airoha: Enable Rx Scatter-Gather - -EN7581 SoC can receive 9k frames. Enable the reception of Scatter-Gather -(SG) frames. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-2-283ebc61120e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 68 ++++++++++++++--------- - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - drivers/net/ethernet/airoha/airoha_regs.h | 5 ++ - 3 files changed, 48 insertions(+), 26 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -615,10 +615,10 @@ static int airoha_qdma_rx_process(struct - struct airoha_qdma_desc *desc = &q->desc[q->tail]; - u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); - dma_addr_t dma_addr = le32_to_cpu(desc->addr); -+ struct page *page = virt_to_head_page(e->buf); - u32 desc_ctrl = le32_to_cpu(desc->ctrl); - struct airoha_gdm_port *port; -- struct sk_buff *skb; -- int len, p; -+ int data_len, len, p; - - if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) - break; -@@ -636,30 +636,41 @@ static int airoha_qdma_rx_process(struct - dma_sync_single_for_cpu(eth->dev, dma_addr, - SKB_WITH_OVERHEAD(q->buf_size), dir); - -+ data_len = q->skb ? q->buf_size -+ : SKB_WITH_OVERHEAD(q->buf_size); -+ if (data_len < len) -+ goto free_frag; -+ - p = airoha_qdma_get_gdm_port(eth, desc); -- if (p < 0 || !eth->ports[p]) { -- page_pool_put_full_page(q->page_pool, -- virt_to_head_page(e->buf), -- true); -- continue; -- } -+ if (p < 0 || !eth->ports[p]) -+ goto free_frag; - - port = eth->ports[p]; -- skb = napi_build_skb(e->buf, q->buf_size); -- if (!skb) { -- page_pool_put_full_page(q->page_pool, -- virt_to_head_page(e->buf), -- true); -- break; -+ if (!q->skb) { /* first buffer */ -+ q->skb = napi_build_skb(e->buf, q->buf_size); -+ if (!q->skb) -+ goto free_frag; -+ -+ __skb_put(q->skb, len); -+ skb_mark_for_recycle(q->skb); -+ q->skb->dev = port->dev; -+ q->skb->protocol = eth_type_trans(q->skb, port->dev); -+ q->skb->ip_summed = CHECKSUM_UNNECESSARY; -+ skb_record_rx_queue(q->skb, qid); -+ } else { /* scattered frame */ -+ struct skb_shared_info *shinfo = skb_shinfo(q->skb); -+ int nr_frags = shinfo->nr_frags; -+ -+ if (nr_frags >= ARRAY_SIZE(shinfo->frags)) -+ goto free_frag; -+ -+ skb_add_rx_frag(q->skb, nr_frags, page, -+ e->buf - page_address(page), len, -+ q->buf_size); - } - -- skb_reserve(skb, 2); -- __skb_put(skb, len); -- skb_mark_for_recycle(skb); -- skb->dev = port->dev; -- skb->protocol = eth_type_trans(skb, skb->dev); -- skb->ip_summed = CHECKSUM_UNNECESSARY; -- skb_record_rx_queue(skb, qid); -+ if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl)) -+ continue; - - if (netdev_uses_dsa(port->dev)) { - /* PPE module requires untagged packets to work -@@ -672,22 +683,27 @@ static int airoha_qdma_rx_process(struct - - if (sptag < ARRAY_SIZE(port->dsa_meta) && - port->dsa_meta[sptag]) -- skb_dst_set_noref(skb, -+ skb_dst_set_noref(q->skb, - &port->dsa_meta[sptag]->dst); - } - - hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1); - if (hash != AIROHA_RXD4_FOE_ENTRY) -- skb_set_hash(skb, jhash_1word(hash, 0), -+ skb_set_hash(q->skb, jhash_1word(hash, 0), - PKT_HASH_TYPE_L4); - - reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); - if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) - airoha_ppe_check_skb(eth->ppe, hash); - -- napi_gro_receive(&q->napi, skb); -- - done++; -+ napi_gro_receive(&q->napi, q->skb); -+ q->skb = NULL; -+ continue; -+free_frag: -+ page_pool_put_full_page(q->page_pool, page, true); -+ dev_kfree_skb(q->skb); -+ q->skb = NULL; - } - airoha_qdma_fill_rx_queue(q); - -@@ -762,6 +778,7 @@ static int airoha_qdma_init_rx_queue(str - FIELD_PREP(RX_RING_THR_MASK, thr)); - airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK, - FIELD_PREP(RX_RING_DMA_IDX_MASK, q->head)); -+ airoha_qdma_set(qdma, REG_RX_SCATTER_CFG(qid), RX_RING_SG_EN_MASK); - - airoha_qdma_fill_rx_queue(q); - -@@ -1182,7 +1199,6 @@ static int airoha_qdma_hw_init(struct ai - } - - airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG, -- GLOBAL_CFG_RX_2B_OFFSET_MASK | - FIELD_PREP(GLOBAL_CFG_DMA_PREFERENCE_MASK, 3) | - GLOBAL_CFG_CPU_TXR_RR_MASK | - GLOBAL_CFG_PAYLOAD_BYTE_SWAP_MASK | ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -176,6 +176,7 @@ struct airoha_queue { - - struct napi_struct napi; - struct page_pool *page_pool; -+ struct sk_buff *skb; - }; - - struct airoha_tx_irq_queue { ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -626,10 +626,15 @@ - #define REG_RX_DELAY_INT_IDX(_n) \ - (((_n) < 16) ? 0x0210 + ((_n) << 5) : 0x0e10 + (((_n) - 16) << 5)) - -+#define REG_RX_SCATTER_CFG(_n) \ -+ (((_n) < 16) ? 0x0214 + ((_n) << 5) : 0x0e14 + (((_n) - 16) << 5)) -+ - #define RX_DELAY_INT_MASK GENMASK(15, 0) - - #define RX_RING_DMA_IDX_MASK GENMASK(15, 0) - -+#define RX_RING_SG_EN_MASK BIT(0) -+ - #define REG_INGRESS_TRTCM_CFG 0x0070 - #define INGRESS_TRTCM_EN_MASK BIT(31) - #define INGRESS_TRTCM_MODE_MASK BIT(30) diff --git a/target/linux/airoha/patches-6.12/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch b/target/linux/airoha/patches-6.12/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch deleted file mode 100644 index ba403459f35..00000000000 --- a/target/linux/airoha/patches-6.12/063-03-v6.15-net-airoha-Introduce-airoha_dev_change_mtu-callback.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 03b1b69f0662c46f258a45e4a7d7837351c11692 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 4 Mar 2025 15:21:10 +0100 -Subject: [PATCH 3/6] net: airoha: Introduce airoha_dev_change_mtu callback - -Add airoha_dev_change_mtu callback to update the MTU of a running -device. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-3-283ebc61120e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1726,6 +1726,20 @@ static void airoha_dev_get_stats64(struc - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } - -+static int airoha_dev_change_mtu(struct net_device *dev, int mtu) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_eth *eth = port->qdma->eth; -+ u32 len = ETH_HLEN + mtu + ETH_FCS_LEN; -+ -+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), -+ GDM_LONG_LEN_MASK, -+ FIELD_PREP(GDM_LONG_LEN_MASK, len)); -+ WRITE_ONCE(dev->mtu, mtu); -+ -+ return 0; -+} -+ - static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, - struct net_device *sb_dev) - { -@@ -2418,6 +2432,7 @@ static const struct net_device_ops airoh - .ndo_init = airoha_dev_init, - .ndo_open = airoha_dev_open, - .ndo_stop = airoha_dev_stop, -+ .ndo_change_mtu = airoha_dev_change_mtu, - .ndo_select_queue = airoha_dev_select_queue, - .ndo_start_xmit = airoha_dev_xmit, - .ndo_get_stats64 = airoha_dev_get_stats64, diff --git a/target/linux/airoha/patches-6.12/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch b/target/linux/airoha/patches-6.12/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch deleted file mode 100644 index 8771ff22db5..00000000000 --- a/target/linux/airoha/patches-6.12/063-04-v6.15-net-airoha-Increase-max-mtu-to-9k.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 168ef0c1dee83c401896a0bca680e9f97b1ebd64 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 4 Mar 2025 15:21:11 +0100 -Subject: [PATCH 4/6] net: airoha: Increase max mtu to 9k - -EN7581 SoC supports 9k maximum MTU. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250304-airoha-eth-rx-sg-v1-4-283ebc61120e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -20,7 +20,7 @@ - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 - #define AIROHA_MAX_NUM_XSI_RSTS 5 --#define AIROHA_MAX_MTU 2000 -+#define AIROHA_MAX_MTU 9216 - #define AIROHA_MAX_PACKET_SIZE 2048 - #define AIROHA_NUM_QOS_CHANNELS 4 - #define AIROHA_NUM_QOS_QUEUES 8 diff --git a/target/linux/airoha/patches-6.12/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch b/target/linux/airoha/patches-6.12/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch deleted file mode 100644 index 1c3030afd0c..00000000000 --- a/target/linux/airoha/patches-6.12/063-05-v6.15-net-airoha-Fix-lan4-support-in-airoha_qdma_get_gdm_p.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 35ea4f06fd33fc32f556a0c26d1d8340497fa7f8 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 4 Mar 2025 15:38:05 +0100 -Subject: [PATCH 5/6] net: airoha: Fix lan4 support in - airoha_qdma_get_gdm_port() - -EN7581 SoC supports lan{1,4} ports on MT7530 DSA switch. Fix lan4 -reported value in airoha_qdma_get_gdm_port routine. - -Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250304-airoha-eth-fix-lan4-v1-1-832417da4bb5@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -589,7 +589,7 @@ static int airoha_qdma_get_gdm_port(stru - - sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); - switch (sport) { -- case 0x10 ... 0x13: -+ case 0x10 ... 0x14: - port = 0; - break; - case 0x2 ... 0x4: diff --git a/target/linux/airoha/patches-6.12/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch b/target/linux/airoha/patches-6.12/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch deleted file mode 100644 index 61d7e5fe4bb..00000000000 --- a/target/linux/airoha/patches-6.12/063-06-v6.15-net-airoha-Enable-TSO-Scatter-Gather-for-LAN-port.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a202dfe31cae2f2120297a7142385d80a5577d42 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 4 Mar 2025 16:46:40 +0100 -Subject: [PATCH 6/6] net: airoha: Enable TSO/Scatter Gather for LAN port - -Set net_device vlan_features in order to enable TSO and Scatter Gather -for DSA user ports. - -Reviewed-by: Mateusz Polchlopek -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250304-lan-enable-tso-v1-1-b398eb9976ba@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2523,6 +2523,7 @@ static int airoha_alloc_gdm_port(struct - NETIF_F_SG | NETIF_F_TSO | - NETIF_F_HW_TC; - dev->features |= dev->hw_features; -+ dev->vlan_features = dev->hw_features; - dev->dev.of_node = np; - dev->irq = qdma->irq; - SET_NETDEV_DEV(dev, eth->dev); diff --git a/target/linux/airoha/patches-6.12/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch b/target/linux/airoha/patches-6.12/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch deleted file mode 100644 index ef8c11de793..00000000000 --- a/target/linux/airoha/patches-6.12/064-v6.15-net-airoha-Fix-dev-dsa_ptr-check-in-airoha_get_dsa_t.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e368d2a1e8b6f0926e4e76a56b484249905192f5 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 6 Mar 2025 11:52:20 +0100 -Subject: [PATCH] net: airoha: Fix dev->dsa_ptr check in airoha_get_dsa_tag() - -Fix the following warning reported by Smatch static checker in -airoha_get_dsa_tag routine: - -drivers/net/ethernet/airoha/airoha_eth.c:1722 airoha_get_dsa_tag() -warn: 'dp' isn't an ERR_PTR - -dev->dsa_ptr can't be set to an error pointer, it can just be NULL. -Remove this check since it is already performed in netdev_uses_dsa(). - -Reported-by: Dan Carpenter -Closes: https://lore.kernel.org/netdev/Z8l3E0lGOcrel07C@lore-desk/T/#m54adc113fcdd8c5e6c5f65ffd60d8e8b1d483d90 -Fixes: af3cf757d5c9 ("net: airoha: Move DSA tag in DMA descriptor") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250306-airoha-flowtable-fixes-v1-1-68d3c1296cdd@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1762,18 +1762,13 @@ static u32 airoha_get_dsa_tag(struct sk_ - { - #if IS_ENABLED(CONFIG_NET_DSA) - struct ethhdr *ehdr; -- struct dsa_port *dp; - u8 xmit_tpid; - u16 tag; - - if (!netdev_uses_dsa(dev)) - return 0; - -- dp = dev->dsa_ptr; -- if (IS_ERR(dp)) -- return 0; -- -- if (dp->tag_ops->proto != DSA_TAG_PROTO_MTK) -+ if (dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) - return 0; - - if (skb_cow_head(skb, 0)) diff --git a/target/linux/airoha/patches-6.12/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch b/target/linux/airoha/patches-6.12/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch deleted file mode 100644 index a8467408ed5..00000000000 --- a/target/linux/airoha/patches-6.12/065-v6.15-net-airoha-fix-CONFIG_DEBUG_FS-check.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 08d0185e36ad8bb5902a73711bf114765d282161 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Fri, 14 Mar 2025 16:49:59 +0100 -Subject: [PATCH] net: airoha: fix CONFIG_DEBUG_FS check - -The #if check causes a build failure when CONFIG_DEBUG_FS is turned -off: - -In file included from drivers/net/ethernet/airoha/airoha_eth.c:17: -drivers/net/ethernet/airoha/airoha_eth.h:543:5: error: "CONFIG_DEBUG_FS" is not defined, evaluates to 0 [-Werror=undef] - 543 | #if CONFIG_DEBUG_FS - | ^~~~~~~~~~~~~~~ - -Replace it with the correct #ifdef. - -Fixes: 3fe15c640f38 ("net: airoha: Introduce PPE debugfs support") -Signed-off-by: Arnd Bergmann -Acked-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250314155009.4114308-1-arnd@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -540,7 +540,7 @@ void airoha_ppe_deinit(struct airoha_eth - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash); - --#if CONFIG_DEBUG_FS -+#ifdef CONFIG_DEBUG_FS - int airoha_ppe_debugfs_init(struct airoha_ppe *ppe); - #else - static inline int airoha_ppe_debugfs_init(struct airoha_ppe *ppe) diff --git a/target/linux/airoha/patches-6.12/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch b/target/linux/airoha/patches-6.12/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch deleted file mode 100644 index bbe441a9d7d..00000000000 --- a/target/linux/airoha/patches-6.12/066-01-v6.15-net-airoha-Fix-qid-report-in-airoha_tc_get_htb_get_l.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 57b290d97c6150774bf929117ca737a26d8fc33d Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 31 Mar 2025 08:52:53 +0200 -Subject: [PATCH 1/2] net: airoha: Fix qid report in - airoha_tc_get_htb_get_leaf_queue() - -Fix the following kernel warning deleting HTB offloaded leafs and/or root -HTB qdisc in airoha_eth driver properly reporting qid in -airoha_tc_get_htb_get_leaf_queue routine. - -$tc qdisc replace dev eth1 root handle 10: htb offload -$tc class add dev eth1 arent 10: classid 10:4 htb rate 100mbit ceil 100mbit -$tc qdisc replace dev eth1 parent 10:4 handle 4: ets bands 8 \ - quanta 1514 3028 4542 6056 7570 9084 10598 12112 -$tc qdisc del dev eth1 root - -[ 55.827864] ------------[ cut here ]------------ -[ 55.832493] WARNING: CPU: 3 PID: 2678 at 0xffffffc0798695a4 -[ 55.956510] CPU: 3 PID: 2678 Comm: tc Tainted: G O 6.6.71 #0 -[ 55.963557] Hardware name: Airoha AN7581 Evaluation Board (DT) -[ 55.969383] pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) -[ 55.976344] pc : 0xffffffc0798695a4 -[ 55.979851] lr : 0xffffffc079869a20 -[ 55.983358] sp : ffffffc0850536a0 -[ 55.986665] x29: ffffffc0850536a0 x28: 0000000000000024 x27: 0000000000000001 -[ 55.993800] x26: 0000000000000000 x25: ffffff8008b19000 x24: ffffff800222e800 -[ 56.000935] x23: 0000000000000001 x22: 0000000000000000 x21: ffffff8008b19000 -[ 56.008071] x20: ffffff8002225800 x19: ffffff800379d000 x18: 0000000000000000 -[ 56.015206] x17: ffffffbf9ea59000 x16: ffffffc080018000 x15: 0000000000000000 -[ 56.022342] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000001 -[ 56.029478] x11: ffffffc081471008 x10: ffffffc081575a98 x9 : 0000000000000000 -[ 56.036614] x8 : ffffffc08167fd40 x7 : ffffffc08069e104 x6 : ffffff8007f86000 -[ 56.043748] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000001 -[ 56.050884] x2 : 0000000000000000 x1 : 0000000000000250 x0 : ffffff800222c000 -[ 56.058020] Call trace: -[ 56.060459] 0xffffffc0798695a4 -[ 56.063618] 0xffffffc079869a20 -[ 56.066777] __qdisc_destroy+0x40/0xa0 -[ 56.070528] qdisc_put+0x54/0x6c -[ 56.073748] qdisc_graft+0x41c/0x648 -[ 56.077324] tc_get_qdisc+0x168/0x2f8 -[ 56.080978] rtnetlink_rcv_msg+0x230/0x330 -[ 56.085076] netlink_rcv_skb+0x5c/0x128 -[ 56.088913] rtnetlink_rcv+0x14/0x1c -[ 56.092490] netlink_unicast+0x1e0/0x2c8 -[ 56.096413] netlink_sendmsg+0x198/0x3c8 -[ 56.100337] ____sys_sendmsg+0x1c4/0x274 -[ 56.104261] ___sys_sendmsg+0x7c/0xc0 -[ 56.107924] __sys_sendmsg+0x44/0x98 -[ 56.111492] __arm64_sys_sendmsg+0x20/0x28 -[ 56.115580] invoke_syscall.constprop.0+0x58/0xfc -[ 56.120285] do_el0_svc+0x3c/0xbc -[ 56.123592] el0_svc+0x18/0x4c -[ 56.126647] el0t_64_sync_handler+0x118/0x124 -[ 56.131005] el0t_64_sync+0x150/0x154 -[ 56.134660] ---[ end trace 0000000000000000 ]--- - -Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support") -Signed-off-by: Lorenzo Bianconi -Acked-by: Paolo Abeni -Link: https://patch.msgid.link/20250331-airoha-htb-qdisc-offload-del-fix-v1-1-4ea429c2c968@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2376,7 +2376,7 @@ static int airoha_tc_get_htb_get_leaf_qu - return -EINVAL; - } - -- opt->qid = channel; -+ opt->qid = AIROHA_NUM_TX_RING + channel; - - return 0; - } diff --git a/target/linux/airoha/patches-6.12/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch b/target/linux/airoha/patches-6.12/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch deleted file mode 100644 index 915fcf6a2b7..00000000000 --- a/target/linux/airoha/patches-6.12/066-02-v6.15-net-airoha-Fix-ETS-priomap-validation.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 367579274f60cb23c570ae5348966ab51e1509a4 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 31 Mar 2025 18:17:31 +0200 -Subject: [PATCH 2/2] net: airoha: Fix ETS priomap validation - -ETS Qdisc schedules SP bands in a priority order assigning band-0 the -highest priority (band-0 > band-1 > .. > band-n) while EN7581 arranges -SP bands in a priority order assigning band-7 the highest priority -(band-7 > band-6, .. > band-n). -Fix priomap check in airoha_qdma_set_tx_ets_sched routine in order to -align ETS Qdisc and airoha_eth driver SP priority ordering. - -Fixes: b56e4d660a96 ("net: airoha: Enforce ETS Qdisc priomap") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Reviewed-by: Davide Caratti -Link: https://patch.msgid.link/20250331-airoha-ets-validate-priomap-v1-1-60a524488672@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2049,7 +2049,7 @@ static int airoha_qdma_set_tx_ets_sched( - struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; - enum tx_sched_mode mode = TC_SCH_SP; - u16 w[AIROHA_NUM_QOS_QUEUES] = {}; -- int i, nstrict = 0, nwrr, qidx; -+ int i, nstrict = 0; - - if (p->bands > AIROHA_NUM_QOS_QUEUES) - return -EINVAL; -@@ -2067,17 +2067,17 @@ static int airoha_qdma_set_tx_ets_sched( - * lowest priorities with respect to SP ones. - * e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn - */ -- nwrr = p->bands - nstrict; -- qidx = nstrict && nwrr ? nstrict : 0; -- for (i = 1; i <= p->bands; i++) { -- if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx) -+ for (i = 0; i < nstrict; i++) { -+ if (p->priomap[p->bands - i - 1] != i) - return -EINVAL; -- -- qidx = i == nwrr ? 0 : qidx + 1; - } - -- for (i = 0; i < nwrr; i++) -+ for (i = 0; i < p->bands - nstrict; i++) { -+ if (p->priomap[i] != nstrict + i) -+ return -EINVAL; -+ - w[i] = p->weights[nstrict + i]; -+ } - - if (!nstrict) - mode = TC_SCH_WRR8; diff --git a/target/linux/airoha/patches-6.12/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch b/target/linux/airoha/patches-6.12/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch deleted file mode 100644 index 2138366d72d..00000000000 --- a/target/linux/airoha/patches-6.12/067-v6.15-net-airoha-Validate-egress-gdm-port-in-airoha_ppe_fo.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 09bccf56db36501ccb1935d921dc24451e9f57dd Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 1 Apr 2025 11:42:30 +0200 -Subject: [PATCH] net: airoha: Validate egress gdm port in - airoha_ppe_foe_entry_prepare() - -Dev pointer in airoha_ppe_foe_entry_prepare routine is not strictly -a device allocated by airoha_eth driver since it is an egress device -and the flowtable can contain even wlan, pppoe or vlan devices. E.g: - -flowtable ft { - hook ingress priority filter - devices = { eth1, lan1, lan2, lan3, lan4, wlan0 } - flags offload ^ - | - "not allocated by airoha_eth" -- -} - -In this case airoha_get_dsa_port() will just return the original device -pointer and we can't assume netdev priv pointer points to an -airoha_gdm_port struct. -Fix the issue validating egress gdm port in airoha_ppe_foe_entry_prepare -routine before accessing net_device priv pointer. - -Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250401-airoha-validate-egress-gdm-port-v4-1-c7315d33ce10@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 13 +++++++++++++ - drivers/net/ethernet/airoha/airoha_eth.h | 3 +++ - drivers/net/ethernet/airoha/airoha_ppe.c | 8 ++++++-- - 3 files changed, 22 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2472,6 +2472,19 @@ static void airoha_metadata_dst_free(str - } - } - -+bool airoha_is_valid_gdm_port(struct airoha_eth *eth, -+ struct airoha_gdm_port *port) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ if (eth->ports[i] == port) -+ return true; -+ } -+ -+ return false; -+} -+ - static int airoha_alloc_gdm_port(struct airoha_eth *eth, - struct device_node *np, int index) - { ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -532,6 +532,9 @@ u32 airoha_rmw(void __iomem *base, u32 o - #define airoha_qdma_clear(qdma, offset, val) \ - airoha_rmw((qdma)->regs, (offset), (val), 0) - -+bool airoha_is_valid_gdm_port(struct airoha_eth *eth, -+ struct airoha_gdm_port *port); -+ - void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); - int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, - void *cb_priv); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -197,7 +197,8 @@ static int airoha_get_dsa_port(struct ne - #endif - } - --static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, -+static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, -+ struct airoha_foe_entry *hwe, - struct net_device *dev, int type, - struct airoha_flow_data *data, - int l4proto) -@@ -225,6 +226,9 @@ static int airoha_ppe_foe_entry_prepare( - struct airoha_gdm_port *port = netdev_priv(dev); - u8 pse_port; - -+ if (!airoha_is_valid_gdm_port(eth, port)) -+ return -EINVAL; -+ - if (dsa_port >= 0) - pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; - else -@@ -633,7 +637,7 @@ static int airoha_ppe_flow_offload_repla - !is_valid_ether_addr(data.eth.h_dest)) - return -EINVAL; - -- err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type, -+ err = airoha_ppe_foe_entry_prepare(eth, &hwe, odev, offload_type, - &data, l4proto); - if (err) - return err; diff --git a/target/linux/airoha/patches-6.12/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch b/target/linux/airoha/patches-6.12/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch deleted file mode 100644 index 95f83f53bdb..00000000000 --- a/target/linux/airoha/patches-6.12/068-01-v6.16-net-airoha-Add-l2_flows-rhashtable.patch +++ /dev/null @@ -1,207 +0,0 @@ -From b4916f67902e2ae1dc8e37dfa45e8894ad2f8921 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 9 Apr 2025 11:47:14 +0200 -Subject: [PATCH 1/2] net: airoha: Add l2_flows rhashtable - -Introduce l2_flows rhashtable in airoha_ppe struct in order to -store L2 flows committed by upper layers of the kernel. This is a -preliminary patch in order to offload L2 traffic rules. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Michal Kubiak -Link: https://patch.msgid.link/20250409-airoha-flowtable-l2b-v2-1-4a1e3935ea92@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.h | 15 +++- - drivers/net/ethernet/airoha/airoha_ppe.c | 103 ++++++++++++++++++----- - 2 files changed, 98 insertions(+), 20 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -422,12 +422,23 @@ struct airoha_flow_data { - } pppoe; - }; - -+enum airoha_flow_entry_type { -+ FLOW_TYPE_L4, -+ FLOW_TYPE_L2, -+ FLOW_TYPE_L2_SUBFLOW, -+}; -+ - struct airoha_flow_table_entry { -- struct hlist_node list; -+ union { -+ struct hlist_node list; /* PPE L3 flow entry */ -+ struct rhash_head l2_node; /* L2 flow entry */ -+ }; - - struct airoha_foe_entry data; - u32 hash; - -+ enum airoha_flow_entry_type type; -+ - struct rhash_head node; - unsigned long cookie; - }; -@@ -480,6 +491,8 @@ struct airoha_ppe { - void *foe; - dma_addr_t foe_dma; - -+ struct rhashtable l2_flows; -+ - struct hlist_head *foe_flow; - u16 foe_check_time[PPE_NUM_ENTRIES]; - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -24,6 +24,13 @@ static const struct rhashtable_params ai - .automatic_shrinking = true, - }; - -+static const struct rhashtable_params airoha_l2_flow_table_params = { -+ .head_offset = offsetof(struct airoha_flow_table_entry, l2_node), -+ .key_offset = offsetof(struct airoha_flow_table_entry, data.bridge), -+ .key_len = 2 * ETH_ALEN, -+ .automatic_shrinking = true, -+}; -+ - static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) - { - return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; -@@ -476,6 +483,43 @@ static int airoha_ppe_foe_commit_entry(s - return 0; - } - -+static void airoha_ppe_foe_remove_flow(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ lockdep_assert_held(&ppe_lock); -+ -+ hlist_del_init(&e->list); -+ if (e->hash != 0xffff) { -+ e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; -+ e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, -+ AIROHA_FOE_STATE_INVALID); -+ airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); -+ e->hash = 0xffff; -+ } -+} -+ -+static void airoha_ppe_foe_remove_l2_flow(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ lockdep_assert_held(&ppe_lock); -+ -+ rhashtable_remove_fast(&ppe->l2_flows, &e->l2_node, -+ airoha_l2_flow_table_params); -+} -+ -+static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ spin_lock_bh(&ppe_lock); -+ -+ if (e->type == FLOW_TYPE_L2) -+ airoha_ppe_foe_remove_l2_flow(ppe, e); -+ else -+ airoha_ppe_foe_remove_flow(ppe, e); -+ -+ spin_unlock_bh(&ppe_lock); -+} -+ - static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, u32 hash) - { - struct airoha_flow_table_entry *e; -@@ -505,11 +549,37 @@ unlock: - spin_unlock_bh(&ppe_lock); - } - -+static int -+airoha_ppe_foe_l2_flow_commit_entry(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ struct airoha_flow_table_entry *prev; -+ -+ e->type = FLOW_TYPE_L2; -+ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &e->l2_node, -+ airoha_l2_flow_table_params); -+ if (!prev) -+ return 0; -+ -+ if (IS_ERR(prev)) -+ return PTR_ERR(prev); -+ -+ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node, -+ &e->l2_node, -+ airoha_l2_flow_table_params); -+} -+ - static int airoha_ppe_foe_flow_commit_entry(struct airoha_ppe *ppe, - struct airoha_flow_table_entry *e) - { -- u32 hash = airoha_ppe_foe_get_entry_hash(&e->data); -+ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, e->data.ib1); -+ u32 hash; - -+ if (type == PPE_PKT_TYPE_BRIDGE) -+ return airoha_ppe_foe_l2_flow_commit_entry(ppe, e); -+ -+ hash = airoha_ppe_foe_get_entry_hash(&e->data); -+ e->type = FLOW_TYPE_L4; - e->hash = 0xffff; - - spin_lock_bh(&ppe_lock); -@@ -519,23 +589,6 @@ static int airoha_ppe_foe_flow_commit_en - return 0; - } - --static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, -- struct airoha_flow_table_entry *e) --{ -- spin_lock_bh(&ppe_lock); -- -- hlist_del_init(&e->list); -- if (e->hash != 0xffff) { -- e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; -- e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, -- AIROHA_FOE_STATE_INVALID); -- airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); -- e->hash = 0xffff; -- } -- -- spin_unlock_bh(&ppe_lock); --} -- - static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, - struct flow_cls_offload *f) - { -@@ -890,9 +943,20 @@ int airoha_ppe_init(struct airoha_eth *e - if (err) - return err; - -+ err = rhashtable_init(&ppe->l2_flows, &airoha_l2_flow_table_params); -+ if (err) -+ goto error_flow_table_destroy; -+ - err = airoha_ppe_debugfs_init(ppe); - if (err) -- rhashtable_destroy(ð->flow_table); -+ goto error_l2_flow_table_destroy; -+ -+ return 0; -+ -+error_l2_flow_table_destroy: -+ rhashtable_destroy(&ppe->l2_flows); -+error_flow_table_destroy: -+ rhashtable_destroy(ð->flow_table); - - return err; - } -@@ -909,6 +973,7 @@ void airoha_ppe_deinit(struct airoha_eth - } - rcu_read_unlock(); - -+ rhashtable_destroy(ð->ppe->l2_flows); - rhashtable_destroy(ð->flow_table); - debugfs_remove(eth->ppe->debugfs_dir); - } diff --git a/target/linux/airoha/patches-6.12/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch b/target/linux/airoha/patches-6.12/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch deleted file mode 100644 index 2375962338b..00000000000 --- a/target/linux/airoha/patches-6.12/068-02-v6.16-net-airoha-Add-L2-hw-acceleration-support.patch +++ /dev/null @@ -1,253 +0,0 @@ -From cd53f622611f9a6dd83b858c85448dd3568b67ec Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 9 Apr 2025 11:47:15 +0200 -Subject: [PATCH 2/2] net: airoha: Add L2 hw acceleration support - -Similar to mtk driver, introduce the capability to offload L2 traffic -defining flower rules in the PSE/PPE engine available on EN7581 SoC. -Since the hw always reports L2/L3/L4 flower rules, link all L2 rules -sharing the same L2 info (with different L3/L4 info) in the L2 subflows -list of a given L2 PPE entry. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Michal Kubiak -Link: https://patch.msgid.link/20250409-airoha-flowtable-l2b-v2-2-4a1e3935ea92@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 2 +- - drivers/net/ethernet/airoha/airoha_eth.h | 9 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 121 ++++++++++++++++++++--- - 3 files changed, 115 insertions(+), 17 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -694,7 +694,7 @@ static int airoha_qdma_rx_process(struct - - reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); - if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -- airoha_ppe_check_skb(eth->ppe, hash); -+ airoha_ppe_check_skb(eth->ppe, q->skb, hash); - - done++; - napi_gro_receive(&q->napi, q->skb); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -431,10 +431,14 @@ enum airoha_flow_entry_type { - struct airoha_flow_table_entry { - union { - struct hlist_node list; /* PPE L3 flow entry */ -- struct rhash_head l2_node; /* L2 flow entry */ -+ struct { -+ struct rhash_head l2_node; /* L2 flow entry */ -+ struct hlist_head l2_flows; /* PPE L2 subflows list */ -+ }; - }; - - struct airoha_foe_entry data; -+ struct hlist_node l2_subflow_node; /* PPE L2 subflow entry */ - u32 hash; - - enum airoha_flow_entry_type type; -@@ -548,7 +552,8 @@ u32 airoha_rmw(void __iomem *base, u32 o - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - --void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); -+void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, -+ u16 hash); - int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, - void *cb_priv); - int airoha_ppe_init(struct airoha_eth *eth); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -204,6 +204,15 @@ static int airoha_get_dsa_port(struct ne - #endif - } - -+static void airoha_ppe_foe_set_bridge_addrs(struct airoha_foe_bridge *br, -+ struct ethhdr *eh) -+{ -+ br->dest_mac_hi = get_unaligned_be32(eh->h_dest); -+ br->dest_mac_lo = get_unaligned_be16(eh->h_dest + 4); -+ br->src_mac_hi = get_unaligned_be16(eh->h_source); -+ br->src_mac_lo = get_unaligned_be32(eh->h_source + 2); -+} -+ - static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, - struct airoha_foe_entry *hwe, - struct net_device *dev, int type, -@@ -254,13 +263,7 @@ static int airoha_ppe_foe_entry_prepare( - - qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f); - if (type == PPE_PKT_TYPE_BRIDGE) { -- hwe->bridge.dest_mac_hi = get_unaligned_be32(data->eth.h_dest); -- hwe->bridge.dest_mac_lo = -- get_unaligned_be16(data->eth.h_dest + 4); -- hwe->bridge.src_mac_hi = -- get_unaligned_be16(data->eth.h_source); -- hwe->bridge.src_mac_lo = -- get_unaligned_be32(data->eth.h_source + 2); -+ airoha_ppe_foe_set_bridge_addrs(&hwe->bridge, &data->eth); - hwe->bridge.data = qdata; - hwe->bridge.ib2 = val; - l2 = &hwe->bridge.l2.common; -@@ -385,6 +388,19 @@ static u32 airoha_ppe_foe_get_entry_hash - hv3 = hwe->ipv6.src_ip[1] ^ hwe->ipv6.dest_ip[1]; - hv3 ^= hwe->ipv6.src_ip[0]; - break; -+ case PPE_PKT_TYPE_BRIDGE: { -+ struct airoha_foe_mac_info *l2 = &hwe->bridge.l2; -+ -+ hv1 = l2->common.src_mac_hi & 0xffff; -+ hv1 = hv1 << 16 | l2->src_mac_lo; -+ -+ hv2 = l2->common.dest_mac_lo; -+ hv2 = hv2 << 16; -+ hv2 = hv2 | ((l2->common.src_mac_hi & 0xffff0000) >> 16); -+ -+ hv3 = l2->common.dest_mac_hi; -+ break; -+ } - case PPE_PKT_TYPE_IPV4_DSLITE: - case PPE_PKT_TYPE_IPV6_6RD: - default: -@@ -496,15 +512,24 @@ static void airoha_ppe_foe_remove_flow(s - airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); - e->hash = 0xffff; - } -+ if (e->type == FLOW_TYPE_L2_SUBFLOW) { -+ hlist_del_init(&e->l2_subflow_node); -+ kfree(e); -+ } - } - - static void airoha_ppe_foe_remove_l2_flow(struct airoha_ppe *ppe, - struct airoha_flow_table_entry *e) - { -+ struct hlist_head *head = &e->l2_flows; -+ struct hlist_node *n; -+ - lockdep_assert_held(&ppe_lock); - - rhashtable_remove_fast(&ppe->l2_flows, &e->l2_node, - airoha_l2_flow_table_params); -+ hlist_for_each_entry_safe(e, n, head, l2_subflow_node) -+ airoha_ppe_foe_remove_flow(ppe, e); - } - - static void airoha_ppe_foe_flow_remove_entry(struct airoha_ppe *ppe, -@@ -520,10 +545,56 @@ static void airoha_ppe_foe_flow_remove_e - spin_unlock_bh(&ppe_lock); - } - --static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, u32 hash) -+static int -+airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e, -+ u32 hash) -+{ -+ u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP; -+ struct airoha_foe_entry *hwe_p, hwe; -+ struct airoha_flow_table_entry *f; -+ struct airoha_foe_mac_info *l2; -+ int type; -+ -+ hwe_p = airoha_ppe_foe_get_entry(ppe, hash); -+ if (!hwe_p) -+ return -EINVAL; -+ -+ f = kzalloc(sizeof(*f), GFP_ATOMIC); -+ if (!f) -+ return -ENOMEM; -+ -+ hlist_add_head(&f->l2_subflow_node, &e->l2_flows); -+ f->type = FLOW_TYPE_L2_SUBFLOW; -+ f->hash = hash; -+ -+ memcpy(&hwe, hwe_p, sizeof(*hwe_p)); -+ hwe.ib1 = (hwe.ib1 & mask) | (e->data.ib1 & ~mask); -+ l2 = &hwe.bridge.l2; -+ memcpy(l2, &e->data.bridge.l2, sizeof(*l2)); -+ -+ type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe.ib1); -+ if (type == PPE_PKT_TYPE_IPV4_HNAPT) -+ memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple, -+ sizeof(hwe.ipv4.new_tuple)); -+ else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T && -+ l2->common.etype == ETH_P_IP) -+ l2->common.etype = ETH_P_IPV6; -+ -+ hwe.bridge.ib2 = e->data.bridge.ib2; -+ airoha_ppe_foe_commit_entry(ppe, &hwe, hash); -+ -+ return 0; -+} -+ -+static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, -+ struct sk_buff *skb, -+ u32 hash) - { - struct airoha_flow_table_entry *e; -+ struct airoha_foe_bridge br = {}; - struct airoha_foe_entry *hwe; -+ bool commit_done = false; - struct hlist_node *n; - u32 index, state; - -@@ -539,12 +610,33 @@ static void airoha_ppe_foe_insert_entry( - - index = airoha_ppe_foe_get_entry_hash(hwe); - hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { -- if (airoha_ppe_foe_compare_entry(e, hwe)) { -- airoha_ppe_foe_commit_entry(ppe, &e->data, hash); -- e->hash = hash; -- break; -+ if (e->type == FLOW_TYPE_L2_SUBFLOW) { -+ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); -+ if (state != AIROHA_FOE_STATE_BIND) { -+ e->hash = 0xffff; -+ airoha_ppe_foe_remove_flow(ppe, e); -+ } -+ continue; -+ } -+ -+ if (commit_done || !airoha_ppe_foe_compare_entry(e, hwe)) { -+ e->hash = 0xffff; -+ continue; - } -+ -+ airoha_ppe_foe_commit_entry(ppe, &e->data, hash); -+ commit_done = true; -+ e->hash = hash; - } -+ -+ if (commit_done) -+ goto unlock; -+ -+ airoha_ppe_foe_set_bridge_addrs(&br, eth_hdr(skb)); -+ e = rhashtable_lookup_fast(&ppe->l2_flows, &br, -+ airoha_l2_flow_table_params); -+ if (e) -+ airoha_ppe_foe_commit_subflow_entry(ppe, e, hash); - unlock: - spin_unlock_bh(&ppe_lock); - } -@@ -899,7 +991,8 @@ int airoha_ppe_setup_tc_block_cb(enum tc - return err; - } - --void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash) -+void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, -+ u16 hash) - { - u16 now, diff; - -@@ -912,7 +1005,7 @@ void airoha_ppe_check_skb(struct airoha_ - return; - - ppe->foe_check_time[hash] = now; -- airoha_ppe_foe_insert_entry(ppe, hash); -+ airoha_ppe_foe_insert_entry(ppe, skb, hash); - } - - int airoha_ppe_init(struct airoha_eth *eth) diff --git a/target/linux/airoha/patches-6.12/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch b/target/linux/airoha/patches-6.12/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch deleted file mode 100644 index 632ac8fd4f6..00000000000 --- a/target/linux/airoha/patches-6.12/069-v6.16-net-airoha-Add-matchall-filter-offload-support.patch +++ /dev/null @@ -1,405 +0,0 @@ -From df8398fb7bb7a0e509200af56b79343aa133b7d6 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 15 Apr 2025 09:14:34 +0200 -Subject: [PATCH] net: airoha: Add matchall filter offload support - -Introduce tc matchall filter offload support in airoha_eth driver. -Matchall hw filter is used to implement hw rate policing via tc action -police: - -$tc qdisc add dev eth0 handle ffff: ingress -$tc filter add dev eth0 parent ffff: matchall action police \ - rate 100mbit burst 1000k drop - -The current implementation supports just drop/accept as exceed/notexceed -actions. Moreover, rate and burst are the only supported configuration -parameters. - -Reviewed-by: Davide Caratti -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250415-airoha-hw-rx-ratelimit-v4-1-03458784fbc3@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 273 +++++++++++++++++++++- - drivers/net/ethernet/airoha/airoha_eth.h | 8 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 9 +- - drivers/net/ethernet/airoha/airoha_regs.h | 7 + - 4 files changed, 286 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -527,6 +527,25 @@ static int airoha_fe_init(struct airoha_ - /* disable IFC by default */ - airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); - -+ airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), -+ FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM1) | -+ FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM1) | -+ FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM1) | -+ FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM1) | -+ FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM1) | -+ FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM1) | -+ FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM1) | -+ FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM1)); -+ airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(1), -+ FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM2) | -+ FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM2) | -+ FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM2) | -+ FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM2) | -+ FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM2) | -+ FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM2) | -+ FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM2) | -+ FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM2)); -+ - /* enable 1:N vlan action, init vlan table */ - airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); - -@@ -1652,7 +1671,6 @@ static void airhoha_set_gdm2_loopback(st - - if (port->id == 3) { - /* FIXME: handle XSI_PCE1_PORT */ -- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), 0x5500); - airoha_fe_rmw(eth, REG_FE_WAN_PORT, - WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, - FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); -@@ -2127,6 +2145,125 @@ static int airoha_tc_setup_qdisc_ets(str - } - } - -+static int airoha_qdma_get_rl_param(struct airoha_qdma *qdma, int queue_id, -+ u32 addr, enum trtcm_param_type param, -+ u32 *val_low, u32 *val_high) -+{ -+ u32 idx = QDMA_METER_IDX(queue_id), group = QDMA_METER_GROUP(queue_id); -+ u32 val, config = FIELD_PREP(RATE_LIMIT_PARAM_TYPE_MASK, param) | -+ FIELD_PREP(RATE_LIMIT_METER_GROUP_MASK, group) | -+ FIELD_PREP(RATE_LIMIT_PARAM_INDEX_MASK, idx); -+ -+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -+ if (read_poll_timeout(airoha_qdma_rr, val, -+ val & RATE_LIMIT_PARAM_RW_DONE_MASK, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, qdma, -+ REG_TRTCM_CFG_PARAM(addr))) -+ return -ETIMEDOUT; -+ -+ *val_low = airoha_qdma_rr(qdma, REG_TRTCM_DATA_LOW(addr)); -+ if (val_high) -+ *val_high = airoha_qdma_rr(qdma, REG_TRTCM_DATA_HIGH(addr)); -+ -+ return 0; -+} -+ -+static int airoha_qdma_set_rl_param(struct airoha_qdma *qdma, int queue_id, -+ u32 addr, enum trtcm_param_type param, -+ u32 val) -+{ -+ u32 idx = QDMA_METER_IDX(queue_id), group = QDMA_METER_GROUP(queue_id); -+ u32 config = RATE_LIMIT_PARAM_RW_MASK | -+ FIELD_PREP(RATE_LIMIT_PARAM_TYPE_MASK, param) | -+ FIELD_PREP(RATE_LIMIT_METER_GROUP_MASK, group) | -+ FIELD_PREP(RATE_LIMIT_PARAM_INDEX_MASK, idx); -+ -+ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val); -+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config); -+ -+ return read_poll_timeout(airoha_qdma_rr, val, -+ val & RATE_LIMIT_PARAM_RW_DONE_MASK, -+ USEC_PER_MSEC, 10 * USEC_PER_MSEC, true, -+ qdma, REG_TRTCM_CFG_PARAM(addr)); -+} -+ -+static int airoha_qdma_set_rl_config(struct airoha_qdma *qdma, int queue_id, -+ u32 addr, bool enable, u32 enable_mask) -+{ -+ u32 val; -+ int err; -+ -+ err = airoha_qdma_get_rl_param(qdma, queue_id, addr, TRTCM_MISC_MODE, -+ &val, NULL); -+ if (err) -+ return err; -+ -+ val = enable ? val | enable_mask : val & ~enable_mask; -+ -+ return airoha_qdma_set_rl_param(qdma, queue_id, addr, TRTCM_MISC_MODE, -+ val); -+} -+ -+static int airoha_qdma_set_rl_token_bucket(struct airoha_qdma *qdma, -+ int queue_id, u32 rate_val, -+ u32 bucket_size) -+{ -+ u32 val, config, tick, unit, rate, rate_frac; -+ int err; -+ -+ err = airoha_qdma_get_rl_param(qdma, queue_id, REG_INGRESS_TRTCM_CFG, -+ TRTCM_MISC_MODE, &config, NULL); -+ if (err) -+ return err; -+ -+ val = airoha_qdma_rr(qdma, REG_INGRESS_TRTCM_CFG); -+ tick = FIELD_GET(INGRESS_FAST_TICK_MASK, val); -+ if (config & TRTCM_TICK_SEL) -+ tick *= FIELD_GET(INGRESS_SLOW_TICK_RATIO_MASK, val); -+ if (!tick) -+ return -EINVAL; -+ -+ unit = (config & TRTCM_PKT_MODE) ? 1000000 / tick : 8000 / tick; -+ if (!unit) -+ return -EINVAL; -+ -+ rate = rate_val / unit; -+ rate_frac = rate_val % unit; -+ rate_frac = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate_frac) / unit; -+ rate = FIELD_PREP(TRTCM_TOKEN_RATE_MASK, rate) | -+ FIELD_PREP(TRTCM_TOKEN_RATE_FRACTION_MASK, rate_frac); -+ -+ err = airoha_qdma_set_rl_param(qdma, queue_id, REG_INGRESS_TRTCM_CFG, -+ TRTCM_TOKEN_RATE_MODE, rate); -+ if (err) -+ return err; -+ -+ val = bucket_size; -+ if (!(config & TRTCM_PKT_MODE)) -+ val = max_t(u32, val, MIN_TOKEN_SIZE); -+ val = min_t(u32, __fls(val), MAX_TOKEN_SIZE_OFFSET); -+ -+ return airoha_qdma_set_rl_param(qdma, queue_id, REG_INGRESS_TRTCM_CFG, -+ TRTCM_BUCKETSIZE_SHIFT_MODE, val); -+} -+ -+static int airoha_qdma_init_rl_config(struct airoha_qdma *qdma, int queue_id, -+ bool enable, enum trtcm_unit_type unit) -+{ -+ bool tick_sel = queue_id == 0 || queue_id == 2 || queue_id == 8; -+ enum trtcm_param mode = TRTCM_METER_MODE; -+ int err; -+ -+ mode |= unit == TRTCM_PACKET_UNIT ? TRTCM_PKT_MODE : 0; -+ err = airoha_qdma_set_rl_config(qdma, queue_id, REG_INGRESS_TRTCM_CFG, -+ enable, mode); -+ if (err) -+ return err; -+ -+ return airoha_qdma_set_rl_config(qdma, queue_id, REG_INGRESS_TRTCM_CFG, -+ tick_sel, TRTCM_TICK_SEL); -+} -+ - static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel, - u32 addr, enum trtcm_param_type param, - enum trtcm_mode_type mode, -@@ -2291,10 +2428,142 @@ static int airoha_tc_htb_alloc_leaf_queu - return 0; - } - -+static int airoha_qdma_set_rx_meter(struct airoha_gdm_port *port, -+ u32 rate, u32 bucket_size, -+ enum trtcm_unit_type unit_type) -+{ -+ struct airoha_qdma *qdma = port->qdma; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ int err; -+ -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ err = airoha_qdma_init_rl_config(qdma, i, !!rate, unit_type); -+ if (err) -+ return err; -+ -+ err = airoha_qdma_set_rl_token_bucket(qdma, i, rate, -+ bucket_size); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int airoha_tc_matchall_act_validate(struct tc_cls_matchall_offload *f) -+{ -+ const struct flow_action *actions = &f->rule->action; -+ const struct flow_action_entry *act; -+ -+ if (!flow_action_has_entries(actions)) { -+ NL_SET_ERR_MSG_MOD(f->common.extack, -+ "filter run with no actions"); -+ return -EINVAL; -+ } -+ -+ if (!flow_offload_has_one_action(actions)) { -+ NL_SET_ERR_MSG_MOD(f->common.extack, -+ "only once action per filter is supported"); -+ return -EOPNOTSUPP; -+ } -+ -+ act = &actions->entries[0]; -+ if (act->id != FLOW_ACTION_POLICE) { -+ NL_SET_ERR_MSG_MOD(f->common.extack, "unsupported action"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) { -+ NL_SET_ERR_MSG_MOD(f->common.extack, -+ "invalid exceed action id"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) { -+ NL_SET_ERR_MSG_MOD(f->common.extack, -+ "invalid notexceed action id"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT && -+ !flow_action_is_last_entry(actions, act)) { -+ NL_SET_ERR_MSG_MOD(f->common.extack, -+ "action accept must be last"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (act->police.peakrate_bytes_ps || act->police.avrate || -+ act->police.overhead || act->police.mtu) { -+ NL_SET_ERR_MSG_MOD(f->common.extack, -+ "peakrate/avrate/overhead/mtu unsupported"); -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int airoha_dev_tc_matchall(struct net_device *dev, -+ struct tc_cls_matchall_offload *f) -+{ -+ enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT; -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ u32 rate = 0, bucket_size = 0; -+ -+ switch (f->command) { -+ case TC_CLSMATCHALL_REPLACE: { -+ const struct flow_action_entry *act; -+ int err; -+ -+ err = airoha_tc_matchall_act_validate(f); -+ if (err) -+ return err; -+ -+ act = &f->rule->action.entries[0]; -+ if (act->police.rate_pkt_ps) { -+ rate = act->police.rate_pkt_ps; -+ bucket_size = act->police.burst_pkt; -+ unit_type = TRTCM_PACKET_UNIT; -+ } else { -+ rate = div_u64(act->police.rate_bytes_ps, 1000); -+ rate = rate << 3; /* Kbps */ -+ bucket_size = act->police.burst; -+ } -+ fallthrough; -+ } -+ case TC_CLSMATCHALL_DESTROY: -+ return airoha_qdma_set_rx_meter(port, rate, bucket_size, -+ unit_type); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type, -+ void *type_data, void *cb_priv) -+{ -+ struct net_device *dev = cb_priv; -+ -+ if (!tc_can_offload(dev)) -+ return -EOPNOTSUPP; -+ -+ switch (type) { -+ case TC_SETUP_CLSFLOWER: -+ return airoha_ppe_setup_tc_block_cb(dev, type_data); -+ case TC_SETUP_CLSMATCHALL: -+ return airoha_dev_tc_matchall(dev, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port, - struct flow_block_offload *f) - { -- flow_setup_cb_t *cb = airoha_ppe_setup_tc_block_cb; -+ flow_setup_cb_t *cb = airoha_dev_setup_tc_block_cb; - static LIST_HEAD(block_cb_list); - struct flow_block_cb *block_cb; - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -127,6 +127,11 @@ enum tx_sched_mode { - TC_SCH_WRR2, - }; - -+enum trtcm_unit_type { -+ TRTCM_BYTE_UNIT, -+ TRTCM_PACKET_UNIT, -+}; -+ - enum trtcm_param_type { - TRTCM_MISC_MODE, /* meter_en, pps_mode, tick_sel */ - TRTCM_TOKEN_RATE_MODE, -@@ -554,8 +559,7 @@ bool airoha_is_valid_gdm_port(struct air - - void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, - u16 hash); --int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, -- void *cb_priv); -+int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data); - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -967,18 +967,13 @@ error_npu_put: - return err; - } - --int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, -- void *cb_priv) -+int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data) - { -- struct flow_cls_offload *cls = type_data; -- struct net_device *dev = cb_priv; - struct airoha_gdm_port *port = netdev_priv(dev); -+ struct flow_cls_offload *cls = type_data; - struct airoha_eth *eth = port->qdma->eth; - int err = 0; - -- if (!tc_can_offload(dev) || type != TC_SETUP_CLSFLOWER) -- return -EOPNOTSUPP; -- - mutex_lock(&flow_offload_mutex); - - if (!eth->npu) ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -283,6 +283,7 @@ - #define PPE_HASH_SEED 0x12345678 - - #define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) -+#define DFT_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) - - #define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) - -@@ -691,6 +692,12 @@ - #define REG_TRTCM_DATA_LOW(_n) ((_n) + 0x8) - #define REG_TRTCM_DATA_HIGH(_n) ((_n) + 0xc) - -+#define RATE_LIMIT_PARAM_RW_MASK BIT(31) -+#define RATE_LIMIT_PARAM_RW_DONE_MASK BIT(30) -+#define RATE_LIMIT_PARAM_TYPE_MASK GENMASK(29, 28) -+#define RATE_LIMIT_METER_GROUP_MASK GENMASK(27, 26) -+#define RATE_LIMIT_PARAM_INDEX_MASK GENMASK(23, 16) -+ - #define REG_TXWRR_MODE_CFG 0x1020 - #define TWRR_WEIGHT_SCALE_MASK BIT(31) - #define TWRR_WEIGHT_BASE_MASK BIT(3) diff --git a/target/linux/airoha/patches-6.12/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch b/target/linux/airoha/patches-6.12/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch deleted file mode 100644 index 773cb12f7e1..00000000000 --- a/target/linux/airoha/patches-6.12/070-01-v6.16-net-airoha-Introduce-airoha_irq_bank-struct.patch +++ /dev/null @@ -1,292 +0,0 @@ -From 9439db26d3ee4a897e5cd108864172531f31ce07 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 18 Apr 2025 12:40:49 +0200 -Subject: [PATCH 1/2] net: airoha: Introduce airoha_irq_bank struct - -EN7581 ethernet SoC supports 4 programmable IRQ lines each one composed -by 4 IRQ configuration registers. Add airoha_irq_bank struct as a -container for independent IRQ lines info (e.g. IRQ number, enabled source -interrupts, ecc). This is a preliminary patch to support multiple IRQ lines -in airoha_eth driver. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250418-airoha-eth-multi-irq-v1-1-1ab0083ca3c1@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 106 ++++++++++++++-------- - drivers/net/ethernet/airoha/airoha_eth.h | 13 ++- - drivers/net/ethernet/airoha/airoha_regs.h | 11 ++- - 3 files changed, 86 insertions(+), 44 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -34,37 +34,40 @@ u32 airoha_rmw(void __iomem *base, u32 o - return val; - } - --static void airoha_qdma_set_irqmask(struct airoha_qdma *qdma, int index, -- u32 clear, u32 set) -+static void airoha_qdma_set_irqmask(struct airoha_irq_bank *irq_bank, -+ int index, u32 clear, u32 set) - { -+ struct airoha_qdma *qdma = irq_bank->qdma; -+ int bank = irq_bank - &qdma->irq_banks[0]; - unsigned long flags; - -- if (WARN_ON_ONCE(index >= ARRAY_SIZE(qdma->irqmask))) -+ if (WARN_ON_ONCE(index >= ARRAY_SIZE(irq_bank->irqmask))) - return; - -- spin_lock_irqsave(&qdma->irq_lock, flags); -+ spin_lock_irqsave(&irq_bank->irq_lock, flags); - -- qdma->irqmask[index] &= ~clear; -- qdma->irqmask[index] |= set; -- airoha_qdma_wr(qdma, REG_INT_ENABLE(index), qdma->irqmask[index]); -+ irq_bank->irqmask[index] &= ~clear; -+ irq_bank->irqmask[index] |= set; -+ airoha_qdma_wr(qdma, REG_INT_ENABLE(bank, index), -+ irq_bank->irqmask[index]); - /* Read irq_enable register in order to guarantee the update above - * completes in the spinlock critical section. - */ -- airoha_qdma_rr(qdma, REG_INT_ENABLE(index)); -+ airoha_qdma_rr(qdma, REG_INT_ENABLE(bank, index)); - -- spin_unlock_irqrestore(&qdma->irq_lock, flags); -+ spin_unlock_irqrestore(&irq_bank->irq_lock, flags); - } - --static void airoha_qdma_irq_enable(struct airoha_qdma *qdma, int index, -- u32 mask) -+static void airoha_qdma_irq_enable(struct airoha_irq_bank *irq_bank, -+ int index, u32 mask) - { -- airoha_qdma_set_irqmask(qdma, index, 0, mask); -+ airoha_qdma_set_irqmask(irq_bank, index, 0, mask); - } - --static void airoha_qdma_irq_disable(struct airoha_qdma *qdma, int index, -- u32 mask) -+static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank, -+ int index, u32 mask) - { -- airoha_qdma_set_irqmask(qdma, index, mask, 0); -+ airoha_qdma_set_irqmask(irq_bank, index, mask, 0); - } - - static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) -@@ -732,6 +735,7 @@ free_frag: - static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) - { - struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); -+ struct airoha_irq_bank *irq_bank = &q->qdma->irq_banks[0]; - int cur, done = 0; - - do { -@@ -740,7 +744,7 @@ static int airoha_qdma_rx_napi_poll(stru - } while (cur && done < budget); - - if (done < budget && napi_complete(napi)) -- airoha_qdma_irq_enable(q->qdma, QDMA_INT_REG_IDX1, -+ airoha_qdma_irq_enable(irq_bank, QDMA_INT_REG_IDX1, - RX_DONE_INT_MASK); - - return done; -@@ -965,7 +969,7 @@ unlock: - } - - if (done < budget && napi_complete(napi)) -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, -+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, - TX_DONE_INT_MASK(id)); - - return done; -@@ -1196,13 +1200,16 @@ static int airoha_qdma_hw_init(struct ai - int i; - - /* clear pending irqs */ -- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) -+ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks[0].irqmask); i++) - airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); - - /* setup irqs */ -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX0, INT_IDX0_MASK); -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX1, INT_IDX1_MASK); -- airoha_qdma_irq_enable(qdma, QDMA_INT_REG_IDX4, INT_IDX4_MASK); -+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, -+ INT_IDX0_MASK); -+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX1, -+ INT_IDX1_MASK); -+ airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX4, -+ INT_IDX4_MASK); - - /* setup irq binding */ - for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -@@ -1247,13 +1254,14 @@ static int airoha_qdma_hw_init(struct ai - - static irqreturn_t airoha_irq_handler(int irq, void *dev_instance) - { -- struct airoha_qdma *qdma = dev_instance; -- u32 intr[ARRAY_SIZE(qdma->irqmask)]; -+ struct airoha_irq_bank *irq_bank = dev_instance; -+ struct airoha_qdma *qdma = irq_bank->qdma; -+ u32 intr[ARRAY_SIZE(irq_bank->irqmask)]; - int i; - -- for (i = 0; i < ARRAY_SIZE(qdma->irqmask); i++) { -+ for (i = 0; i < ARRAY_SIZE(intr); i++) { - intr[i] = airoha_qdma_rr(qdma, REG_INT_STATUS(i)); -- intr[i] &= qdma->irqmask[i]; -+ intr[i] &= irq_bank->irqmask[i]; - airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]); - } - -@@ -1261,7 +1269,7 @@ static irqreturn_t airoha_irq_handler(in - return IRQ_NONE; - - if (intr[1] & RX_DONE_INT_MASK) { -- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX1, -+ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX1, - RX_DONE_INT_MASK); - - for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -@@ -1278,7 +1286,7 @@ static irqreturn_t airoha_irq_handler(in - if (!(intr[0] & TX_DONE_INT_MASK(i))) - continue; - -- airoha_qdma_irq_disable(qdma, QDMA_INT_REG_IDX0, -+ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX0, - TX_DONE_INT_MASK(i)); - napi_schedule(&qdma->q_tx_irq[i].napi); - } -@@ -1287,6 +1295,39 @@ static irqreturn_t airoha_irq_handler(in - return IRQ_HANDLED; - } - -+static int airoha_qdma_init_irq_banks(struct platform_device *pdev, -+ struct airoha_qdma *qdma) -+{ -+ struct airoha_eth *eth = qdma->eth; -+ int i, id = qdma - ð->qdma[0]; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { -+ struct airoha_irq_bank *irq_bank = &qdma->irq_banks[i]; -+ int err, irq_index = 4 * id + i; -+ const char *name; -+ -+ spin_lock_init(&irq_bank->irq_lock); -+ irq_bank->qdma = qdma; -+ -+ irq_bank->irq = platform_get_irq(pdev, irq_index); -+ if (irq_bank->irq < 0) -+ return irq_bank->irq; -+ -+ name = devm_kasprintf(eth->dev, GFP_KERNEL, -+ KBUILD_MODNAME ".%d", irq_index); -+ if (!name) -+ return -ENOMEM; -+ -+ err = devm_request_irq(eth->dev, irq_bank->irq, -+ airoha_irq_handler, IRQF_SHARED, name, -+ irq_bank); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ - static int airoha_qdma_init(struct platform_device *pdev, - struct airoha_eth *eth, - struct airoha_qdma *qdma) -@@ -1294,9 +1335,7 @@ static int airoha_qdma_init(struct platf - int err, id = qdma - ð->qdma[0]; - const char *res; - -- spin_lock_init(&qdma->irq_lock); - qdma->eth = eth; -- - res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id); - if (!res) - return -ENOMEM; -@@ -1306,12 +1345,7 @@ static int airoha_qdma_init(struct platf - return dev_err_probe(eth->dev, PTR_ERR(qdma->regs), - "failed to iomap qdma%d regs\n", id); - -- qdma->irq = platform_get_irq(pdev, 4 * id); -- if (qdma->irq < 0) -- return qdma->irq; -- -- err = devm_request_irq(eth->dev, qdma->irq, airoha_irq_handler, -- IRQF_SHARED, KBUILD_MODNAME, qdma); -+ err = airoha_qdma_init_irq_banks(pdev, qdma); - if (err) - return err; - -@@ -2802,7 +2836,7 @@ static int airoha_alloc_gdm_port(struct - dev->features |= dev->hw_features; - dev->vlan_features = dev->hw_features; - dev->dev.of_node = np; -- dev->irq = qdma->irq; -+ dev->irq = qdma->irq_banks[0].irq; - SET_NETDEV_DEV(dev, eth->dev); - - /* reserve hw queues for HTB offloading */ ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -17,6 +17,7 @@ - - #define AIROHA_MAX_NUM_GDM_PORTS 4 - #define AIROHA_MAX_NUM_QDMA 2 -+#define AIROHA_MAX_NUM_IRQ_BANKS 1 - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 - #define AIROHA_MAX_NUM_XSI_RSTS 5 -@@ -452,17 +453,23 @@ struct airoha_flow_table_entry { - unsigned long cookie; - }; - --struct airoha_qdma { -- struct airoha_eth *eth; -- void __iomem *regs; -+struct airoha_irq_bank { -+ struct airoha_qdma *qdma; - - /* protect concurrent irqmask accesses */ - spinlock_t irq_lock; - u32 irqmask[QDMA_INT_REG_MAX]; - int irq; -+}; -+ -+struct airoha_qdma { -+ struct airoha_eth *eth; -+ void __iomem *regs; - - atomic_t users; - -+ struct airoha_irq_bank irq_banks[AIROHA_MAX_NUM_IRQ_BANKS]; -+ - struct airoha_tx_irq_queue q_tx_irq[AIROHA_NUM_TX_IRQ]; - - struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -423,11 +423,12 @@ - ((_n) == 2) ? 0x0720 : \ - ((_n) == 1) ? 0x0024 : 0x0020) - --#define REG_INT_ENABLE(_n) \ -- (((_n) == 4) ? 0x0750 : \ -- ((_n) == 3) ? 0x0744 : \ -- ((_n) == 2) ? 0x0740 : \ -- ((_n) == 1) ? 0x002c : 0x0028) -+#define REG_INT_ENABLE(_b, _n) \ -+ (((_n) == 4) ? 0x0750 + ((_b) << 5) : \ -+ ((_n) == 3) ? 0x0744 + ((_b) << 5) : \ -+ ((_n) == 2) ? 0x0740 + ((_b) << 5) : \ -+ ((_n) == 1) ? 0x002c + ((_b) << 3) : \ -+ 0x0028 + ((_b) << 3)) - - /* QDMA_CSR_INT_ENABLE1 */ - #define RX15_COHERENT_INT_MASK BIT(31) diff --git a/target/linux/airoha/patches-6.12/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch b/target/linux/airoha/patches-6.12/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch deleted file mode 100644 index 2d1ad281e54..00000000000 --- a/target/linux/airoha/patches-6.12/070-02-v6.16-net-airoha-Enable-multiple-IRQ-lines-support-in-airo.patch +++ /dev/null @@ -1,379 +0,0 @@ -From f252493e1835366fc25ce631c3056f900977dd11 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 18 Apr 2025 12:40:50 +0200 -Subject: [PATCH 2/2] net: airoha: Enable multiple IRQ lines support in - airoha_eth driver. - -EN7581 ethernet SoC supports 4 programmable IRQ lines for Tx and Rx -interrupts. Enable multiple IRQ lines support. Map Rx/Tx queues to the -available IRQ lines using the default scheme used in the vendor SDK: - -- IRQ0: rx queues [0-4],[7-9],15 -- IRQ1: rx queues [21-30] -- IRQ2: rx queues 5 -- IRQ3: rx queues 6 - -Tx queues interrupts are managed by IRQ0. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250418-airoha-eth-multi-irq-v1-2-1ab0083ca3c1@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 67 +++++--- - drivers/net/ethernet/airoha/airoha_eth.h | 13 +- - drivers/net/ethernet/airoha/airoha_regs.h | 185 +++++++++++++++++----- - 3 files changed, 206 insertions(+), 59 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -735,7 +735,6 @@ free_frag: - static int airoha_qdma_rx_napi_poll(struct napi_struct *napi, int budget) - { - struct airoha_queue *q = container_of(napi, struct airoha_queue, napi); -- struct airoha_irq_bank *irq_bank = &q->qdma->irq_banks[0]; - int cur, done = 0; - - do { -@@ -743,9 +742,20 @@ static int airoha_qdma_rx_napi_poll(stru - done += cur; - } while (cur && done < budget); - -- if (done < budget && napi_complete(napi)) -- airoha_qdma_irq_enable(irq_bank, QDMA_INT_REG_IDX1, -- RX_DONE_INT_MASK); -+ if (done < budget && napi_complete(napi)) { -+ struct airoha_qdma *qdma = q->qdma; -+ int i, qid = q - &qdma->q_rx[0]; -+ int intr_reg = qid < RX_DONE_HIGH_OFFSET ? QDMA_INT_REG_IDX1 -+ : QDMA_INT_REG_IDX2; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { -+ if (!(BIT(qid) & RX_IRQ_BANK_PIN_MASK(i))) -+ continue; -+ -+ airoha_qdma_irq_enable(&qdma->irq_banks[i], intr_reg, -+ BIT(qid % RX_DONE_HIGH_OFFSET)); -+ } -+ } - - return done; - } -@@ -1199,17 +1209,24 @@ static int airoha_qdma_hw_init(struct ai - { - int i; - -- /* clear pending irqs */ -- for (i = 0; i < ARRAY_SIZE(qdma->irq_banks[0].irqmask); i++) -+ for (i = 0; i < ARRAY_SIZE(qdma->irq_banks); i++) { -+ /* clear pending irqs */ - airoha_qdma_wr(qdma, REG_INT_STATUS(i), 0xffffffff); -- -- /* setup irqs */ -+ /* setup rx irqs */ -+ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX0, -+ INT_RX0_MASK(RX_IRQ_BANK_PIN_MASK(i))); -+ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX1, -+ INT_RX1_MASK(RX_IRQ_BANK_PIN_MASK(i))); -+ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX2, -+ INT_RX2_MASK(RX_IRQ_BANK_PIN_MASK(i))); -+ airoha_qdma_irq_enable(&qdma->irq_banks[i], QDMA_INT_REG_IDX3, -+ INT_RX3_MASK(RX_IRQ_BANK_PIN_MASK(i))); -+ } -+ /* setup tx irqs */ - airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX0, -- INT_IDX0_MASK); -- airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX1, -- INT_IDX1_MASK); -+ TX_COHERENT_LOW_INT_MASK | INT_TX_MASK); - airoha_qdma_irq_enable(&qdma->irq_banks[0], QDMA_INT_REG_IDX4, -- INT_IDX4_MASK); -+ TX_COHERENT_HIGH_INT_MASK); - - /* setup irq binding */ - for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -@@ -1256,6 +1273,7 @@ static irqreturn_t airoha_irq_handler(in - { - struct airoha_irq_bank *irq_bank = dev_instance; - struct airoha_qdma *qdma = irq_bank->qdma; -+ u32 rx_intr_mask = 0, rx_intr1, rx_intr2; - u32 intr[ARRAY_SIZE(irq_bank->irqmask)]; - int i; - -@@ -1268,17 +1286,24 @@ static irqreturn_t airoha_irq_handler(in - if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state)) - return IRQ_NONE; - -- if (intr[1] & RX_DONE_INT_MASK) { -- airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX1, -- RX_DONE_INT_MASK); -+ rx_intr1 = intr[1] & RX_DONE_LOW_INT_MASK; -+ if (rx_intr1) { -+ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX1, rx_intr1); -+ rx_intr_mask |= rx_intr1; -+ } - -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- if (!qdma->q_rx[i].ndesc) -- continue; -+ rx_intr2 = intr[2] & RX_DONE_HIGH_INT_MASK; -+ if (rx_intr2) { -+ airoha_qdma_irq_disable(irq_bank, QDMA_INT_REG_IDX2, rx_intr2); -+ rx_intr_mask |= (rx_intr2 << 16); -+ } - -- if (intr[1] & BIT(i)) -- napi_schedule(&qdma->q_rx[i].napi); -- } -+ for (i = 0; rx_intr_mask && i < ARRAY_SIZE(qdma->q_rx); i++) { -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ if (rx_intr_mask & BIT(i)) -+ napi_schedule(&qdma->q_rx[i].napi); - } - - if (intr[0] & INT_TX_MASK) { ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -17,7 +17,7 @@ - - #define AIROHA_MAX_NUM_GDM_PORTS 4 - #define AIROHA_MAX_NUM_QDMA 2 --#define AIROHA_MAX_NUM_IRQ_BANKS 1 -+#define AIROHA_MAX_NUM_IRQ_BANKS 4 - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 - #define AIROHA_MAX_NUM_XSI_RSTS 5 -@@ -453,6 +453,17 @@ struct airoha_flow_table_entry { - unsigned long cookie; - }; - -+/* RX queue to IRQ mapping: BIT(q) in IRQ(n) */ -+#define RX_IRQ0_BANK_PIN_MASK 0x839f -+#define RX_IRQ1_BANK_PIN_MASK 0x7fe00000 -+#define RX_IRQ2_BANK_PIN_MASK 0x20 -+#define RX_IRQ3_BANK_PIN_MASK 0x40 -+#define RX_IRQ_BANK_PIN_MASK(_n) \ -+ (((_n) == 3) ? RX_IRQ3_BANK_PIN_MASK : \ -+ ((_n) == 2) ? RX_IRQ2_BANK_PIN_MASK : \ -+ ((_n) == 1) ? RX_IRQ1_BANK_PIN_MASK : \ -+ RX_IRQ0_BANK_PIN_MASK) -+ - struct airoha_irq_bank { - struct airoha_qdma *qdma; - ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -463,6 +463,26 @@ - #define IRQ0_FULL_INT_MASK BIT(1) - #define IRQ0_INT_MASK BIT(0) - -+#define RX_COHERENT_LOW_INT_MASK \ -+ (RX15_COHERENT_INT_MASK | RX14_COHERENT_INT_MASK | \ -+ RX13_COHERENT_INT_MASK | RX12_COHERENT_INT_MASK | \ -+ RX11_COHERENT_INT_MASK | RX10_COHERENT_INT_MASK | \ -+ RX9_COHERENT_INT_MASK | RX8_COHERENT_INT_MASK | \ -+ RX7_COHERENT_INT_MASK | RX6_COHERENT_INT_MASK | \ -+ RX5_COHERENT_INT_MASK | RX4_COHERENT_INT_MASK | \ -+ RX3_COHERENT_INT_MASK | RX2_COHERENT_INT_MASK | \ -+ RX1_COHERENT_INT_MASK | RX0_COHERENT_INT_MASK) -+ -+#define RX_COHERENT_LOW_OFFSET __ffs(RX_COHERENT_LOW_INT_MASK) -+#define INT_RX0_MASK(_n) \ -+ (((_n) << RX_COHERENT_LOW_OFFSET) & RX_COHERENT_LOW_INT_MASK) -+ -+#define TX_COHERENT_LOW_INT_MASK \ -+ (TX7_COHERENT_INT_MASK | TX6_COHERENT_INT_MASK | \ -+ TX5_COHERENT_INT_MASK | TX4_COHERENT_INT_MASK | \ -+ TX3_COHERENT_INT_MASK | TX2_COHERENT_INT_MASK | \ -+ TX1_COHERENT_INT_MASK | TX0_COHERENT_INT_MASK) -+ - #define TX_DONE_INT_MASK(_n) \ - ((_n) ? IRQ1_INT_MASK | IRQ1_FULL_INT_MASK \ - : IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) -@@ -471,17 +491,6 @@ - (IRQ1_INT_MASK | IRQ1_FULL_INT_MASK | \ - IRQ0_INT_MASK | IRQ0_FULL_INT_MASK) - --#define INT_IDX0_MASK \ -- (TX0_COHERENT_INT_MASK | TX1_COHERENT_INT_MASK | \ -- TX2_COHERENT_INT_MASK | TX3_COHERENT_INT_MASK | \ -- TX4_COHERENT_INT_MASK | TX5_COHERENT_INT_MASK | \ -- TX6_COHERENT_INT_MASK | TX7_COHERENT_INT_MASK | \ -- RX0_COHERENT_INT_MASK | RX1_COHERENT_INT_MASK | \ -- RX2_COHERENT_INT_MASK | RX3_COHERENT_INT_MASK | \ -- RX4_COHERENT_INT_MASK | RX7_COHERENT_INT_MASK | \ -- RX8_COHERENT_INT_MASK | RX9_COHERENT_INT_MASK | \ -- RX15_COHERENT_INT_MASK | INT_TX_MASK) -- - /* QDMA_CSR_INT_ENABLE2 */ - #define RX15_NO_CPU_DSCP_INT_MASK BIT(31) - #define RX14_NO_CPU_DSCP_INT_MASK BIT(30) -@@ -516,19 +525,121 @@ - #define RX1_DONE_INT_MASK BIT(1) - #define RX0_DONE_INT_MASK BIT(0) - --#define RX_DONE_INT_MASK \ -- (RX0_DONE_INT_MASK | RX1_DONE_INT_MASK | \ -- RX2_DONE_INT_MASK | RX3_DONE_INT_MASK | \ -- RX4_DONE_INT_MASK | RX7_DONE_INT_MASK | \ -- RX8_DONE_INT_MASK | RX9_DONE_INT_MASK | \ -- RX15_DONE_INT_MASK) --#define INT_IDX1_MASK \ -- (RX_DONE_INT_MASK | \ -- RX0_NO_CPU_DSCP_INT_MASK | RX1_NO_CPU_DSCP_INT_MASK | \ -- RX2_NO_CPU_DSCP_INT_MASK | RX3_NO_CPU_DSCP_INT_MASK | \ -- RX4_NO_CPU_DSCP_INT_MASK | RX7_NO_CPU_DSCP_INT_MASK | \ -- RX8_NO_CPU_DSCP_INT_MASK | RX9_NO_CPU_DSCP_INT_MASK | \ -- RX15_NO_CPU_DSCP_INT_MASK) -+#define RX_NO_CPU_DSCP_LOW_INT_MASK \ -+ (RX15_NO_CPU_DSCP_INT_MASK | RX14_NO_CPU_DSCP_INT_MASK | \ -+ RX13_NO_CPU_DSCP_INT_MASK | RX12_NO_CPU_DSCP_INT_MASK | \ -+ RX11_NO_CPU_DSCP_INT_MASK | RX10_NO_CPU_DSCP_INT_MASK | \ -+ RX9_NO_CPU_DSCP_INT_MASK | RX8_NO_CPU_DSCP_INT_MASK | \ -+ RX7_NO_CPU_DSCP_INT_MASK | RX6_NO_CPU_DSCP_INT_MASK | \ -+ RX5_NO_CPU_DSCP_INT_MASK | RX4_NO_CPU_DSCP_INT_MASK | \ -+ RX3_NO_CPU_DSCP_INT_MASK | RX2_NO_CPU_DSCP_INT_MASK | \ -+ RX1_NO_CPU_DSCP_INT_MASK | RX0_NO_CPU_DSCP_INT_MASK) -+ -+#define RX_DONE_LOW_INT_MASK \ -+ (RX15_DONE_INT_MASK | RX14_DONE_INT_MASK | \ -+ RX13_DONE_INT_MASK | RX12_DONE_INT_MASK | \ -+ RX11_DONE_INT_MASK | RX10_DONE_INT_MASK | \ -+ RX9_DONE_INT_MASK | RX8_DONE_INT_MASK | \ -+ RX7_DONE_INT_MASK | RX6_DONE_INT_MASK | \ -+ RX5_DONE_INT_MASK | RX4_DONE_INT_MASK | \ -+ RX3_DONE_INT_MASK | RX2_DONE_INT_MASK | \ -+ RX1_DONE_INT_MASK | RX0_DONE_INT_MASK) -+ -+#define RX_NO_CPU_DSCP_LOW_OFFSET __ffs(RX_NO_CPU_DSCP_LOW_INT_MASK) -+#define INT_RX1_MASK(_n) \ -+ ((((_n) << RX_NO_CPU_DSCP_LOW_OFFSET) & RX_NO_CPU_DSCP_LOW_INT_MASK) | \ -+ (RX_DONE_LOW_INT_MASK & (_n))) -+ -+/* QDMA_CSR_INT_ENABLE3 */ -+#define RX31_NO_CPU_DSCP_INT_MASK BIT(31) -+#define RX30_NO_CPU_DSCP_INT_MASK BIT(30) -+#define RX29_NO_CPU_DSCP_INT_MASK BIT(29) -+#define RX28_NO_CPU_DSCP_INT_MASK BIT(28) -+#define RX27_NO_CPU_DSCP_INT_MASK BIT(27) -+#define RX26_NO_CPU_DSCP_INT_MASK BIT(26) -+#define RX25_NO_CPU_DSCP_INT_MASK BIT(25) -+#define RX24_NO_CPU_DSCP_INT_MASK BIT(24) -+#define RX23_NO_CPU_DSCP_INT_MASK BIT(23) -+#define RX22_NO_CPU_DSCP_INT_MASK BIT(22) -+#define RX21_NO_CPU_DSCP_INT_MASK BIT(21) -+#define RX20_NO_CPU_DSCP_INT_MASK BIT(20) -+#define RX19_NO_CPU_DSCP_INT_MASK BIT(19) -+#define RX18_NO_CPU_DSCP_INT_MASK BIT(18) -+#define RX17_NO_CPU_DSCP_INT_MASK BIT(17) -+#define RX16_NO_CPU_DSCP_INT_MASK BIT(16) -+#define RX31_DONE_INT_MASK BIT(15) -+#define RX30_DONE_INT_MASK BIT(14) -+#define RX29_DONE_INT_MASK BIT(13) -+#define RX28_DONE_INT_MASK BIT(12) -+#define RX27_DONE_INT_MASK BIT(11) -+#define RX26_DONE_INT_MASK BIT(10) -+#define RX25_DONE_INT_MASK BIT(9) -+#define RX24_DONE_INT_MASK BIT(8) -+#define RX23_DONE_INT_MASK BIT(7) -+#define RX22_DONE_INT_MASK BIT(6) -+#define RX21_DONE_INT_MASK BIT(5) -+#define RX20_DONE_INT_MASK BIT(4) -+#define RX19_DONE_INT_MASK BIT(3) -+#define RX18_DONE_INT_MASK BIT(2) -+#define RX17_DONE_INT_MASK BIT(1) -+#define RX16_DONE_INT_MASK BIT(0) -+ -+#define RX_NO_CPU_DSCP_HIGH_INT_MASK \ -+ (RX31_NO_CPU_DSCP_INT_MASK | RX30_NO_CPU_DSCP_INT_MASK | \ -+ RX29_NO_CPU_DSCP_INT_MASK | RX28_NO_CPU_DSCP_INT_MASK | \ -+ RX27_NO_CPU_DSCP_INT_MASK | RX26_NO_CPU_DSCP_INT_MASK | \ -+ RX25_NO_CPU_DSCP_INT_MASK | RX24_NO_CPU_DSCP_INT_MASK | \ -+ RX23_NO_CPU_DSCP_INT_MASK | RX22_NO_CPU_DSCP_INT_MASK | \ -+ RX21_NO_CPU_DSCP_INT_MASK | RX20_NO_CPU_DSCP_INT_MASK | \ -+ RX19_NO_CPU_DSCP_INT_MASK | RX18_NO_CPU_DSCP_INT_MASK | \ -+ RX17_NO_CPU_DSCP_INT_MASK | RX16_NO_CPU_DSCP_INT_MASK) -+ -+#define RX_DONE_HIGH_INT_MASK \ -+ (RX31_DONE_INT_MASK | RX30_DONE_INT_MASK | \ -+ RX29_DONE_INT_MASK | RX28_DONE_INT_MASK | \ -+ RX27_DONE_INT_MASK | RX26_DONE_INT_MASK | \ -+ RX25_DONE_INT_MASK | RX24_DONE_INT_MASK | \ -+ RX23_DONE_INT_MASK | RX22_DONE_INT_MASK | \ -+ RX21_DONE_INT_MASK | RX20_DONE_INT_MASK | \ -+ RX19_DONE_INT_MASK | RX18_DONE_INT_MASK | \ -+ RX17_DONE_INT_MASK | RX16_DONE_INT_MASK) -+ -+#define RX_DONE_INT_MASK (RX_DONE_HIGH_INT_MASK | RX_DONE_LOW_INT_MASK) -+#define RX_DONE_HIGH_OFFSET fls(RX_DONE_HIGH_INT_MASK) -+ -+#define INT_RX2_MASK(_n) \ -+ ((RX_NO_CPU_DSCP_HIGH_INT_MASK & (_n)) | \ -+ (((_n) >> RX_DONE_HIGH_OFFSET) & RX_DONE_HIGH_INT_MASK)) -+ -+/* QDMA_CSR_INT_ENABLE4 */ -+#define RX31_COHERENT_INT_MASK BIT(31) -+#define RX30_COHERENT_INT_MASK BIT(30) -+#define RX29_COHERENT_INT_MASK BIT(29) -+#define RX28_COHERENT_INT_MASK BIT(28) -+#define RX27_COHERENT_INT_MASK BIT(27) -+#define RX26_COHERENT_INT_MASK BIT(26) -+#define RX25_COHERENT_INT_MASK BIT(25) -+#define RX24_COHERENT_INT_MASK BIT(24) -+#define RX23_COHERENT_INT_MASK BIT(23) -+#define RX22_COHERENT_INT_MASK BIT(22) -+#define RX21_COHERENT_INT_MASK BIT(21) -+#define RX20_COHERENT_INT_MASK BIT(20) -+#define RX19_COHERENT_INT_MASK BIT(19) -+#define RX18_COHERENT_INT_MASK BIT(18) -+#define RX17_COHERENT_INT_MASK BIT(17) -+#define RX16_COHERENT_INT_MASK BIT(16) -+ -+#define RX_COHERENT_HIGH_INT_MASK \ -+ (RX31_COHERENT_INT_MASK | RX30_COHERENT_INT_MASK | \ -+ RX29_COHERENT_INT_MASK | RX28_COHERENT_INT_MASK | \ -+ RX27_COHERENT_INT_MASK | RX26_COHERENT_INT_MASK | \ -+ RX25_COHERENT_INT_MASK | RX24_COHERENT_INT_MASK | \ -+ RX23_COHERENT_INT_MASK | RX22_COHERENT_INT_MASK | \ -+ RX21_COHERENT_INT_MASK | RX20_COHERENT_INT_MASK | \ -+ RX19_COHERENT_INT_MASK | RX18_COHERENT_INT_MASK | \ -+ RX17_COHERENT_INT_MASK | RX16_COHERENT_INT_MASK) -+ -+#define INT_RX3_MASK(_n) (RX_COHERENT_HIGH_INT_MASK & (_n)) - - /* QDMA_CSR_INT_ENABLE5 */ - #define TX31_COHERENT_INT_MASK BIT(31) -@@ -556,19 +667,19 @@ - #define TX9_COHERENT_INT_MASK BIT(9) - #define TX8_COHERENT_INT_MASK BIT(8) - --#define INT_IDX4_MASK \ -- (TX8_COHERENT_INT_MASK | TX9_COHERENT_INT_MASK | \ -- TX10_COHERENT_INT_MASK | TX11_COHERENT_INT_MASK | \ -- TX12_COHERENT_INT_MASK | TX13_COHERENT_INT_MASK | \ -- TX14_COHERENT_INT_MASK | TX15_COHERENT_INT_MASK | \ -- TX16_COHERENT_INT_MASK | TX17_COHERENT_INT_MASK | \ -- TX18_COHERENT_INT_MASK | TX19_COHERENT_INT_MASK | \ -- TX20_COHERENT_INT_MASK | TX21_COHERENT_INT_MASK | \ -- TX22_COHERENT_INT_MASK | TX23_COHERENT_INT_MASK | \ -- TX24_COHERENT_INT_MASK | TX25_COHERENT_INT_MASK | \ -- TX26_COHERENT_INT_MASK | TX27_COHERENT_INT_MASK | \ -- TX28_COHERENT_INT_MASK | TX29_COHERENT_INT_MASK | \ -- TX30_COHERENT_INT_MASK | TX31_COHERENT_INT_MASK) -+#define TX_COHERENT_HIGH_INT_MASK \ -+ (TX31_COHERENT_INT_MASK | TX30_COHERENT_INT_MASK | \ -+ TX29_COHERENT_INT_MASK | TX28_COHERENT_INT_MASK | \ -+ TX27_COHERENT_INT_MASK | TX26_COHERENT_INT_MASK | \ -+ TX25_COHERENT_INT_MASK | TX24_COHERENT_INT_MASK | \ -+ TX23_COHERENT_INT_MASK | TX22_COHERENT_INT_MASK | \ -+ TX21_COHERENT_INT_MASK | TX20_COHERENT_INT_MASK | \ -+ TX19_COHERENT_INT_MASK | TX18_COHERENT_INT_MASK | \ -+ TX17_COHERENT_INT_MASK | TX16_COHERENT_INT_MASK | \ -+ TX15_COHERENT_INT_MASK | TX14_COHERENT_INT_MASK | \ -+ TX13_COHERENT_INT_MASK | TX12_COHERENT_INT_MASK | \ -+ TX11_COHERENT_INT_MASK | TX10_COHERENT_INT_MASK | \ -+ TX9_COHERENT_INT_MASK | TX8_COHERENT_INT_MASK) - - #define REG_TX_IRQ_BASE(_n) ((_n) ? 0x0048 : 0x0050) - diff --git a/target/linux/airoha/patches-6.12/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch b/target/linux/airoha/patches-6.12/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch deleted file mode 100644 index 2fb90b6c3b7..00000000000 --- a/target/linux/airoha/patches-6.12/071-v6.15-net-airoha-Add-missing-field-to-ppe_mbox_data-struct.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 4a7843cc8a41b9612becccc07715ed017770eb89 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 6 May 2025 18:56:47 +0200 -Subject: [PATCH] net: airoha: Add missing field to ppe_mbox_data struct - -The official Airoha EN7581 firmware requires adding max_packet field in -ppe_mbox_data struct while the unofficial one used to develop the Airoha -EN7581 flowtable support does not require this field. -This patch does not introduce any real backwards compatible issue since -EN7581 fw is not publicly available in linux-firmware or other -repositories (e.g. OpenWrt) yet and the official fw version will use this -new layout. For this reason this change needs to be backported. -Moreover, make explicit the padding added by the compiler introducing -the rsv array in init_info struct. -At the same time use u32 instead of int for init_info and set_info -struct definitions in ppe_mbox_data struct. - -Fixes: 23290c7bc190d ("net: airoha: Introduce Airoha NPU support") -Reviewed-by: Simon Horman -Reviewed-by: Jacob Keller -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250506-airoha-en7581-fix-ppe_mbox_data-v5-1-29cabed6864d@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -104,12 +104,14 @@ struct ppe_mbox_data { - u8 xpon_hal_api; - u8 wan_xsi; - u8 ct_joyme4; -- int ppe_type; -- int wan_mode; -- int wan_sel; -+ u8 max_packet; -+ u8 rsv[3]; -+ u32 ppe_type; -+ u32 wan_mode; -+ u32 wan_sel; - } init_info; - struct { -- int func_id; -+ u32 func_id; - u32 size; - u32 data; - } set_info; diff --git a/target/linux/airoha/patches-6.12/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch b/target/linux/airoha/patches-6.12/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch deleted file mode 100644 index bcf60ce8dd8..00000000000 --- a/target/linux/airoha/patches-6.12/072-v6.15-net-airoha-Fix-page-recycling-in-airoha_qdma_rx_proc.patch +++ /dev/null @@ -1,72 +0,0 @@ -From d6d2b0e1538d5c381ec0ca95afaf772c096ea5dc Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 15 May 2025 08:33:06 +0200 -Subject: [PATCH] net: airoha: Fix page recycling in airoha_qdma_rx_process() - -Do not recycle the page twice in airoha_qdma_rx_process routine in case -of error. Just run dev_kfree_skb() if the skb has been allocated and marked -for recycling. Run page_pool_put_full_page() directly if the skb has not -been allocated yet. -Moreover, rely on DMA address from queue entry element instead of reading -it from the DMA descriptor for DMA syncing in airoha_qdma_rx_process(). - -Fixes: e12182ddb6e71 ("net: airoha: Enable Rx Scatter-Gather") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250515-airoha-fix-rx-process-error-condition-v2-1-657e92c894b9@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -636,7 +636,6 @@ static int airoha_qdma_rx_process(struct - struct airoha_queue_entry *e = &q->entry[q->tail]; - struct airoha_qdma_desc *desc = &q->desc[q->tail]; - u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); -- dma_addr_t dma_addr = le32_to_cpu(desc->addr); - struct page *page = virt_to_head_page(e->buf); - u32 desc_ctrl = le32_to_cpu(desc->ctrl); - struct airoha_gdm_port *port; -@@ -645,22 +644,16 @@ static int airoha_qdma_rx_process(struct - if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) - break; - -- if (!dma_addr) -- break; -- -- len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); -- if (!len) -- break; -- - q->tail = (q->tail + 1) % q->ndesc; - q->queued--; - -- dma_sync_single_for_cpu(eth->dev, dma_addr, -+ dma_sync_single_for_cpu(eth->dev, e->dma_addr, - SKB_WITH_OVERHEAD(q->buf_size), dir); - -+ len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); - data_len = q->skb ? q->buf_size - : SKB_WITH_OVERHEAD(q->buf_size); -- if (data_len < len) -+ if (!len || data_len < len) - goto free_frag; - - p = airoha_qdma_get_gdm_port(eth, desc); -@@ -723,9 +716,12 @@ static int airoha_qdma_rx_process(struct - q->skb = NULL; - continue; - free_frag: -- page_pool_put_full_page(q->page_pool, page, true); -- dev_kfree_skb(q->skb); -- q->skb = NULL; -+ if (q->skb) { -+ dev_kfree_skb(q->skb); -+ q->skb = NULL; -+ } else { -+ page_pool_put_full_page(q->page_pool, page, true); -+ } - } - airoha_qdma_fill_rx_queue(q); - diff --git a/target/linux/airoha/patches-6.12/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch b/target/linux/airoha/patches-6.12/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch deleted file mode 100644 index f0c41d5dc4e..00000000000 --- a/target/linux/airoha/patches-6.12/073-01-v6.16-net-airoha-npu-Move-memory-allocation-in-airoha_npu_.patch +++ /dev/null @@ -1,196 +0,0 @@ -From c52918744ee1e49cea86622a2633b9782446428f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 16 May 2025 09:59:59 +0200 -Subject: [PATCH 1/3] net: airoha: npu: Move memory allocation in - airoha_npu_send_msg() caller - -Move ppe_mbox_data struct memory allocation from airoha_npu_send_msg -routine to the caller one. This is a preliminary patch to enable wlan NPU -offloading and flow counter stats support. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250516-airoha-en7581-flowstats-v2-1-06d5fbf28984@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 126 +++++++++++++---------- - 1 file changed, 72 insertions(+), 54 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -124,17 +124,12 @@ static int airoha_npu_send_msg(struct ai - u16 core = 0; /* FIXME */ - u32 val, offset = core << 4; - dma_addr_t dma_addr; -- void *addr; - int ret; - -- addr = kmemdup(p, size, GFP_ATOMIC); -- if (!addr) -- return -ENOMEM; -- -- dma_addr = dma_map_single(npu->dev, addr, size, DMA_TO_DEVICE); -+ dma_addr = dma_map_single(npu->dev, p, size, DMA_TO_DEVICE); - ret = dma_mapping_error(npu->dev, dma_addr); - if (ret) -- goto out; -+ return ret; - - spin_lock_bh(&npu->cores[core].lock); - -@@ -155,8 +150,6 @@ static int airoha_npu_send_msg(struct ai - spin_unlock_bh(&npu->cores[core].lock); - - dma_unmap_single(npu->dev, dma_addr, size, DMA_TO_DEVICE); --out: -- kfree(addr); - - return ret; - } -@@ -261,76 +254,101 @@ static irqreturn_t airoha_npu_wdt_handle - - static int airoha_npu_ppe_init(struct airoha_npu *npu) - { -- struct ppe_mbox_data ppe_data = { -- .func_type = NPU_OP_SET, -- .func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT, -- .init_info = { -- .ppe_type = PPE_TYPE_L2B_IPV4_IPV6, -- .wan_mode = QDMA_WAN_ETHER, -- }, -- }; -+ struct ppe_mbox_data *ppe_data; -+ int err; - -- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -- sizeof(struct ppe_mbox_data)); -+ ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); -+ if (!ppe_data) -+ return -ENOMEM; -+ -+ ppe_data->func_type = NPU_OP_SET; -+ ppe_data->func_id = PPE_FUNC_SET_WAIT_HWNAT_INIT; -+ ppe_data->init_info.ppe_type = PPE_TYPE_L2B_IPV4_IPV6; -+ ppe_data->init_info.wan_mode = QDMA_WAN_ETHER; -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, -+ sizeof(*ppe_data)); -+ kfree(ppe_data); -+ -+ return err; - } - - static int airoha_npu_ppe_deinit(struct airoha_npu *npu) - { -- struct ppe_mbox_data ppe_data = { -- .func_type = NPU_OP_SET, -- .func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT, -- }; -+ struct ppe_mbox_data *ppe_data; -+ int err; -+ -+ ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); -+ if (!ppe_data) -+ return -ENOMEM; - -- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -- sizeof(struct ppe_mbox_data)); -+ ppe_data->func_type = NPU_OP_SET; -+ ppe_data->func_id = PPE_FUNC_SET_WAIT_HWNAT_DEINIT; -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, -+ sizeof(*ppe_data)); -+ kfree(ppe_data); -+ -+ return err; - } - - static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu, - dma_addr_t foe_addr, - int sram_num_entries) - { -- struct ppe_mbox_data ppe_data = { -- .func_type = NPU_OP_SET, -- .func_id = PPE_FUNC_SET_WAIT_API, -- .set_info = { -- .func_id = PPE_SRAM_RESET_VAL, -- .data = foe_addr, -- .size = sram_num_entries, -- }, -- }; -+ struct ppe_mbox_data *ppe_data; -+ int err; -+ -+ ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); -+ if (!ppe_data) -+ return -ENOMEM; -+ -+ ppe_data->func_type = NPU_OP_SET; -+ ppe_data->func_id = PPE_FUNC_SET_WAIT_API; -+ ppe_data->set_info.func_id = PPE_SRAM_RESET_VAL; -+ ppe_data->set_info.data = foe_addr; -+ ppe_data->set_info.size = sram_num_entries; -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, -+ sizeof(*ppe_data)); -+ kfree(ppe_data); - -- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -- sizeof(struct ppe_mbox_data)); -+ return err; - } - - static int airoha_npu_foe_commit_entry(struct airoha_npu *npu, - dma_addr_t foe_addr, - u32 entry_size, u32 hash, bool ppe2) - { -- struct ppe_mbox_data ppe_data = { -- .func_type = NPU_OP_SET, -- .func_id = PPE_FUNC_SET_WAIT_API, -- .set_info = { -- .data = foe_addr, -- .size = entry_size, -- }, -- }; -+ struct ppe_mbox_data *ppe_data; - int err; - -- ppe_data.set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY -- : PPE_SRAM_SET_ENTRY; -+ ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); -+ if (!ppe_data) -+ return -ENOMEM; -+ -+ ppe_data->func_type = NPU_OP_SET; -+ ppe_data->func_id = PPE_FUNC_SET_WAIT_API; -+ ppe_data->set_info.data = foe_addr; -+ ppe_data->set_info.size = entry_size; -+ ppe_data->set_info.func_id = ppe2 ? PPE2_SRAM_SET_ENTRY -+ : PPE_SRAM_SET_ENTRY; - -- err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -- sizeof(struct ppe_mbox_data)); -+ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, -+ sizeof(*ppe_data)); - if (err) -- return err; -+ goto out; - -- ppe_data.set_info.func_id = PPE_SRAM_SET_VAL; -- ppe_data.set_info.data = hash; -- ppe_data.set_info.size = sizeof(u32); -+ ppe_data->set_info.func_id = PPE_SRAM_SET_VAL; -+ ppe_data->set_info.data = hash; -+ ppe_data->set_info.size = sizeof(u32); -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, -+ sizeof(*ppe_data)); -+out: -+ kfree(ppe_data); - -- return airoha_npu_send_msg(npu, NPU_FUNC_PPE, &ppe_data, -- sizeof(struct ppe_mbox_data)); -+ return err; - } - - struct airoha_npu *airoha_npu_get(struct device *dev) diff --git a/target/linux/airoha/patches-6.12/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch b/target/linux/airoha/patches-6.12/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch deleted file mode 100644 index 584ddb1da8f..00000000000 --- a/target/linux/airoha/patches-6.12/073-02-v6.16-net-airoha-Add-FLOW_CLS_STATS-callback-support.patch +++ /dev/null @@ -1,633 +0,0 @@ -From b81e0f2b58be37628b2e12f8dffdd63c84573e75 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 16 May 2025 10:00:00 +0200 -Subject: [PATCH 2/3] net: airoha: Add FLOW_CLS_STATS callback support - -Introduce per-flow stats accounting to the flowtable hw offload in -the airoha_eth driver. Flow stats are split in the PPE and NPU modules: -- PPE: accounts for high 32bit of per-flow stats -- NPU: accounts for low 32bit of per-flow stats - -FLOW_CLS_STATS can be enabled or disabled at compile time. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250516-airoha-en7581-flowstats-v2-2-06d5fbf28984@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/Kconfig | 7 + - drivers/net/ethernet/airoha/airoha_eth.h | 33 +++ - drivers/net/ethernet/airoha/airoha_npu.c | 52 +++- - drivers/net/ethernet/airoha/airoha_npu.h | 4 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 269 ++++++++++++++++-- - .../net/ethernet/airoha/airoha_ppe_debugfs.c | 9 +- - 6 files changed, 354 insertions(+), 20 deletions(-) - ---- a/drivers/net/ethernet/airoha/Kconfig -+++ b/drivers/net/ethernet/airoha/Kconfig -@@ -24,4 +24,11 @@ config NET_AIROHA - This driver supports the gigabit ethernet MACs in the - Airoha SoC family. - -+config NET_AIROHA_FLOW_STATS -+ default y -+ bool "Airoha flow stats" -+ depends on NET_AIROHA && NET_AIROHA_NPU -+ help -+ Enable Aiorha flowtable statistic counters. -+ - endif #NET_VENDOR_AIROHA ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -50,6 +50,14 @@ - #define PPE_NUM 2 - #define PPE1_SRAM_NUM_ENTRIES (8 * 1024) - #define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) -+#ifdef CONFIG_NET_AIROHA_FLOW_STATS -+#define PPE1_STATS_NUM_ENTRIES (4 * 1024) -+#else -+#define PPE1_STATS_NUM_ENTRIES 0 -+#endif /* CONFIG_NET_AIROHA_FLOW_STATS */ -+#define PPE_STATS_NUM_ENTRIES (2 * PPE1_STATS_NUM_ENTRIES) -+#define PPE1_SRAM_NUM_DATA_ENTRIES (PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES) -+#define PPE_SRAM_NUM_DATA_ENTRIES (2 * PPE1_SRAM_NUM_DATA_ENTRIES) - #define PPE_DRAM_NUM_ENTRIES (16 * 1024) - #define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) - #define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) -@@ -261,6 +269,8 @@ struct airoha_foe_mac_info { - - u16 pppoe_id; - u16 src_mac_lo; -+ -+ u32 meter; - }; - - #define AIROHA_FOE_IB1_UNBIND_PREBIND BIT(24) -@@ -296,6 +306,11 @@ struct airoha_foe_mac_info { - #define AIROHA_FOE_TUNNEL BIT(6) - #define AIROHA_FOE_TUNNEL_ID GENMASK(5, 0) - -+#define AIROHA_FOE_TUNNEL_MTU GENMASK(31, 16) -+#define AIROHA_FOE_ACNT_GRP3 GENMASK(15, 9) -+#define AIROHA_FOE_METER_GRP3 GENMASK(8, 5) -+#define AIROHA_FOE_METER_GRP2 GENMASK(4, 0) -+ - struct airoha_foe_bridge { - u32 dest_mac_hi; - -@@ -379,6 +394,8 @@ struct airoha_foe_ipv6 { - u32 ib2; - - struct airoha_foe_mac_info_common l2; -+ -+ u32 meter; - }; - - struct airoha_foe_entry { -@@ -397,6 +414,16 @@ struct airoha_foe_entry { - }; - }; - -+struct airoha_foe_stats { -+ u32 bytes; -+ u32 packets; -+}; -+ -+struct airoha_foe_stats64 { -+ u64 bytes; -+ u64 packets; -+}; -+ - struct airoha_flow_data { - struct ethhdr eth; - -@@ -447,6 +474,7 @@ struct airoha_flow_table_entry { - struct hlist_node l2_subflow_node; /* PPE L2 subflow entry */ - u32 hash; - -+ struct airoha_foe_stats64 stats; - enum airoha_flow_entry_type type; - - struct rhash_head node; -@@ -523,6 +551,9 @@ struct airoha_ppe { - struct hlist_head *foe_flow; - u16 foe_check_time[PPE_NUM_ENTRIES]; - -+ struct airoha_foe_stats *foe_stats; -+ dma_addr_t foe_stats_dma; -+ - struct dentry *debugfs_dir; - }; - -@@ -582,6 +613,8 @@ int airoha_ppe_init(struct airoha_eth *e - void airoha_ppe_deinit(struct airoha_eth *eth); - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash); -+void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, -+ struct airoha_foe_stats64 *stats); - - #ifdef CONFIG_DEBUG_FS - int airoha_ppe_debugfs_init(struct airoha_ppe *ppe); ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -12,6 +12,7 @@ - #include - #include - -+#include "airoha_eth.h" - #include "airoha_npu.h" - - #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" -@@ -72,6 +73,7 @@ enum { - PPE_FUNC_SET_WAIT_HWNAT_INIT, - PPE_FUNC_SET_WAIT_HWNAT_DEINIT, - PPE_FUNC_SET_WAIT_API, -+ PPE_FUNC_SET_WAIT_FLOW_STATS_SETUP, - }; - - enum { -@@ -115,6 +117,10 @@ struct ppe_mbox_data { - u32 size; - u32 data; - } set_info; -+ struct { -+ u32 npu_stats_addr; -+ u32 foe_stats_addr; -+ } stats_info; - }; - }; - -@@ -351,7 +357,40 @@ out: - return err; - } - --struct airoha_npu *airoha_npu_get(struct device *dev) -+static int airoha_npu_stats_setup(struct airoha_npu *npu, -+ dma_addr_t foe_stats_addr) -+{ -+ int err, size = PPE_STATS_NUM_ENTRIES * sizeof(*npu->stats); -+ struct ppe_mbox_data *ppe_data; -+ -+ if (!size) /* flow stats are disabled */ -+ return 0; -+ -+ ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); -+ if (!ppe_data) -+ return -ENOMEM; -+ -+ ppe_data->func_type = NPU_OP_SET; -+ ppe_data->func_id = PPE_FUNC_SET_WAIT_FLOW_STATS_SETUP; -+ ppe_data->stats_info.foe_stats_addr = foe_stats_addr; -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_PPE, ppe_data, -+ sizeof(*ppe_data)); -+ if (err) -+ goto out; -+ -+ npu->stats = devm_ioremap(npu->dev, -+ ppe_data->stats_info.npu_stats_addr, -+ size); -+ if (!npu->stats) -+ err = -ENOMEM; -+out: -+ kfree(ppe_data); -+ -+ return err; -+} -+ -+struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) - { - struct platform_device *pdev; - struct device_node *np; -@@ -389,6 +428,17 @@ struct airoha_npu *airoha_npu_get(struct - goto error_module_put; - } - -+ if (stats_addr) { -+ int err; -+ -+ err = airoha_npu_stats_setup(npu, *stats_addr); -+ if (err) { -+ dev_err(dev, "failed to allocate npu stats buffer\n"); -+ npu = ERR_PTR(err); -+ goto error_module_put; -+ } -+ } -+ - return npu; - - error_module_put: ---- a/drivers/net/ethernet/airoha/airoha_npu.h -+++ b/drivers/net/ethernet/airoha/airoha_npu.h -@@ -17,6 +17,8 @@ struct airoha_npu { - struct work_struct wdt_work; - } cores[NPU_NUM_CORES]; - -+ struct airoha_foe_stats __iomem *stats; -+ - struct { - int (*ppe_init)(struct airoha_npu *npu); - int (*ppe_deinit)(struct airoha_npu *npu); -@@ -30,5 +32,5 @@ struct airoha_npu { - } ops; - }; - --struct airoha_npu *airoha_npu_get(struct device *dev); -+struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); - void airoha_npu_put(struct airoha_npu *npu); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -102,7 +102,7 @@ static void airoha_ppe_hw_init(struct ai - - if (airoha_ppe2_is_enabled(eth)) { - sram_num_entries = -- PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_ENTRIES); -+ PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES); - airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), - PPE_SRAM_TB_NUM_ENTRY_MASK | - PPE_DRAM_TB_NUM_ENTRY_MASK, -@@ -119,7 +119,7 @@ static void airoha_ppe_hw_init(struct ai - dram_num_entries)); - } else { - sram_num_entries = -- PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_ENTRIES); -+ PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_DATA_ENTRIES); - airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), - PPE_SRAM_TB_NUM_ENTRY_MASK | - PPE_DRAM_TB_NUM_ENTRY_MASK, -@@ -417,6 +417,77 @@ static u32 airoha_ppe_foe_get_entry_hash - return hash; - } - -+static u32 airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, u32 hash) -+{ -+ if (!airoha_ppe2_is_enabled(ppe->eth)) -+ return hash; -+ -+ return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES -+ : hash; -+} -+ -+static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe, -+ struct airoha_npu *npu, -+ int index) -+{ -+ memset_io(&npu->stats[index], 0, sizeof(*npu->stats)); -+ memset(&ppe->foe_stats[index], 0, sizeof(*ppe->foe_stats)); -+} -+ -+static void airoha_ppe_foe_flow_stats_reset(struct airoha_ppe *ppe, -+ struct airoha_npu *npu) -+{ -+ int i; -+ -+ for (i = 0; i < PPE_STATS_NUM_ENTRIES; i++) -+ airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, i); -+} -+ -+static void airoha_ppe_foe_flow_stats_update(struct airoha_ppe *ppe, -+ struct airoha_npu *npu, -+ struct airoha_foe_entry *hwe, -+ u32 hash) -+{ -+ int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); -+ u32 index, pse_port, val, *data, *ib2, *meter; -+ u8 nbq; -+ -+ index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); -+ if (index >= PPE_STATS_NUM_ENTRIES) -+ return; -+ -+ if (type == PPE_PKT_TYPE_BRIDGE) { -+ data = &hwe->bridge.data; -+ ib2 = &hwe->bridge.ib2; -+ meter = &hwe->bridge.l2.meter; -+ } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { -+ data = &hwe->ipv6.data; -+ ib2 = &hwe->ipv6.ib2; -+ meter = &hwe->ipv6.meter; -+ } else { -+ data = &hwe->ipv4.data; -+ ib2 = &hwe->ipv4.ib2; -+ meter = &hwe->ipv4.l2.meter; -+ } -+ -+ airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, index); -+ -+ val = FIELD_GET(AIROHA_FOE_CHANNEL | AIROHA_FOE_QID, *data); -+ *data = (*data & ~AIROHA_FOE_ACTDP) | -+ FIELD_PREP(AIROHA_FOE_ACTDP, val); -+ -+ val = *ib2 & (AIROHA_FOE_IB2_NBQ | AIROHA_FOE_IB2_PSE_PORT | -+ AIROHA_FOE_IB2_PSE_QOS | AIROHA_FOE_IB2_FAST_PATH); -+ *meter |= FIELD_PREP(AIROHA_FOE_TUNNEL_MTU, val); -+ -+ pse_port = FIELD_GET(AIROHA_FOE_IB2_PSE_PORT, *ib2); -+ nbq = pse_port == 1 ? 6 : 5; -+ *ib2 &= ~(AIROHA_FOE_IB2_NBQ | AIROHA_FOE_IB2_PSE_PORT | -+ AIROHA_FOE_IB2_PSE_QOS); -+ *ib2 |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, 6) | -+ FIELD_PREP(AIROHA_FOE_IB2_NBQ, nbq); -+} -+ - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash) - { -@@ -470,6 +541,8 @@ static int airoha_ppe_foe_commit_entry(s - struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); - u32 ts = airoha_ppe_get_timestamp(ppe); - struct airoha_eth *eth = ppe->eth; -+ struct airoha_npu *npu; -+ int err = 0; - - memcpy(&hwe->d, &e->d, sizeof(*hwe) - sizeof(hwe->ib1)); - wmb(); -@@ -478,25 +551,28 @@ static int airoha_ppe_foe_commit_entry(s - e->ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_TIMESTAMP, ts); - hwe->ib1 = e->ib1; - -+ rcu_read_lock(); -+ -+ npu = rcu_dereference(eth->npu); -+ if (!npu) { -+ err = -ENODEV; -+ goto unlock; -+ } -+ -+ airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); -+ - if (hash < PPE_SRAM_NUM_ENTRIES) { - dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); - bool ppe2 = airoha_ppe2_is_enabled(eth) && - hash >= PPE1_SRAM_NUM_ENTRIES; -- struct airoha_npu *npu; -- int err = -ENODEV; -- -- rcu_read_lock(); -- npu = rcu_dereference(eth->npu); -- if (npu) -- err = npu->ops.ppe_foe_commit_entry(npu, addr, -- sizeof(*hwe), hash, -- ppe2); -- rcu_read_unlock(); - -- return err; -+ err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), -+ hash, ppe2); - } -+unlock: -+ rcu_read_unlock(); - -- return 0; -+ return err; - } - - static void airoha_ppe_foe_remove_flow(struct airoha_ppe *ppe, -@@ -582,6 +658,7 @@ airoha_ppe_foe_commit_subflow_entry(stru - l2->common.etype = ETH_P_IPV6; - - hwe.bridge.ib2 = e->data.bridge.ib2; -+ hwe.bridge.data = e->data.bridge.data; - airoha_ppe_foe_commit_entry(ppe, &hwe, hash); - - return 0; -@@ -681,6 +758,98 @@ static int airoha_ppe_foe_flow_commit_en - return 0; - } - -+static int airoha_ppe_get_entry_idle_time(struct airoha_ppe *ppe, u32 ib1) -+{ -+ u32 state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, ib1); -+ u32 ts, ts_mask, now = airoha_ppe_get_timestamp(ppe); -+ int idle; -+ -+ if (state == AIROHA_FOE_STATE_BIND) { -+ ts = FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, ib1); -+ ts_mask = AIROHA_FOE_IB1_BIND_TIMESTAMP; -+ } else { -+ ts = FIELD_GET(AIROHA_FOE_IB1_UNBIND_TIMESTAMP, ib1); -+ now = FIELD_GET(AIROHA_FOE_IB1_UNBIND_TIMESTAMP, now); -+ ts_mask = AIROHA_FOE_IB1_UNBIND_TIMESTAMP; -+ } -+ idle = now - ts; -+ -+ return idle < 0 ? idle + ts_mask + 1 : idle; -+} -+ -+static void -+airoha_ppe_foe_flow_l2_entry_update(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ int min_idle = airoha_ppe_get_entry_idle_time(ppe, e->data.ib1); -+ struct airoha_flow_table_entry *iter; -+ struct hlist_node *n; -+ -+ lockdep_assert_held(&ppe_lock); -+ -+ hlist_for_each_entry_safe(iter, n, &e->l2_flows, l2_subflow_node) { -+ struct airoha_foe_entry *hwe; -+ u32 ib1, state; -+ int idle; -+ -+ hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); -+ ib1 = READ_ONCE(hwe->ib1); -+ -+ state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, ib1); -+ if (state != AIROHA_FOE_STATE_BIND) { -+ iter->hash = 0xffff; -+ airoha_ppe_foe_remove_flow(ppe, iter); -+ continue; -+ } -+ -+ idle = airoha_ppe_get_entry_idle_time(ppe, ib1); -+ if (idle >= min_idle) -+ continue; -+ -+ min_idle = idle; -+ e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_TIMESTAMP; -+ e->data.ib1 |= ib1 & AIROHA_FOE_IB1_BIND_TIMESTAMP; -+ } -+} -+ -+static void airoha_ppe_foe_flow_entry_update(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ struct airoha_foe_entry *hwe_p, hwe = {}; -+ -+ spin_lock_bh(&ppe_lock); -+ -+ if (e->type == FLOW_TYPE_L2) { -+ airoha_ppe_foe_flow_l2_entry_update(ppe, e); -+ goto unlock; -+ } -+ -+ if (e->hash == 0xffff) -+ goto unlock; -+ -+ hwe_p = airoha_ppe_foe_get_entry(ppe, e->hash); -+ if (!hwe_p) -+ goto unlock; -+ -+ memcpy(&hwe, hwe_p, sizeof(*hwe_p)); -+ if (!airoha_ppe_foe_compare_entry(e, &hwe)) { -+ e->hash = 0xffff; -+ goto unlock; -+ } -+ -+ e->data.ib1 = hwe.ib1; -+unlock: -+ spin_unlock_bh(&ppe_lock); -+} -+ -+static int airoha_ppe_entry_idle_time(struct airoha_ppe *ppe, -+ struct airoha_flow_table_entry *e) -+{ -+ airoha_ppe_foe_flow_entry_update(ppe, e); -+ -+ return airoha_ppe_get_entry_idle_time(ppe, e->data.ib1); -+} -+ - static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, - struct flow_cls_offload *f) - { -@@ -896,6 +1065,60 @@ static int airoha_ppe_flow_offload_destr - return 0; - } - -+void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, -+ struct airoha_foe_stats64 *stats) -+{ -+ u32 index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); -+ struct airoha_eth *eth = ppe->eth; -+ struct airoha_npu *npu; -+ -+ if (index >= PPE_STATS_NUM_ENTRIES) -+ return; -+ -+ rcu_read_lock(); -+ -+ npu = rcu_dereference(eth->npu); -+ if (npu) { -+ u64 packets = ppe->foe_stats[index].packets; -+ u64 bytes = ppe->foe_stats[index].bytes; -+ struct airoha_foe_stats npu_stats; -+ -+ memcpy_fromio(&npu_stats, &npu->stats[index], -+ sizeof(*npu->stats)); -+ stats->packets = packets << 32 | npu_stats.packets; -+ stats->bytes = bytes << 32 | npu_stats.bytes; -+ } -+ -+ rcu_read_unlock(); -+} -+ -+static int airoha_ppe_flow_offload_stats(struct airoha_gdm_port *port, -+ struct flow_cls_offload *f) -+{ -+ struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_flow_table_entry *e; -+ u32 idle; -+ -+ e = rhashtable_lookup(ð->flow_table, &f->cookie, -+ airoha_flow_table_params); -+ if (!e) -+ return -ENOENT; -+ -+ idle = airoha_ppe_entry_idle_time(eth->ppe, e); -+ f->stats.lastused = jiffies - idle * HZ; -+ -+ if (e->hash != 0xffff) { -+ struct airoha_foe_stats64 stats = {}; -+ -+ airoha_ppe_foe_entry_get_stats(eth->ppe, e->hash, &stats); -+ f->stats.pkts += (stats.packets - e->stats.packets); -+ f->stats.bytes += (stats.bytes - e->stats.bytes); -+ e->stats = stats; -+ } -+ -+ return 0; -+} -+ - static int airoha_ppe_flow_offload_cmd(struct airoha_gdm_port *port, - struct flow_cls_offload *f) - { -@@ -904,6 +1127,8 @@ static int airoha_ppe_flow_offload_cmd(s - return airoha_ppe_flow_offload_replace(port, f); - case FLOW_CLS_DESTROY: - return airoha_ppe_flow_offload_destroy(port, f); -+ case FLOW_CLS_STATS: -+ return airoha_ppe_flow_offload_stats(port, f); - default: - break; - } -@@ -929,11 +1154,12 @@ static int airoha_ppe_flush_sram_entries - - static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) - { -- struct airoha_npu *npu = airoha_npu_get(eth->dev); -+ struct airoha_npu *npu = airoha_npu_get(eth->dev, -+ ð->ppe->foe_stats_dma); - - if (IS_ERR(npu)) { - request_module("airoha-npu"); -- npu = airoha_npu_get(eth->dev); -+ npu = airoha_npu_get(eth->dev, ð->ppe->foe_stats_dma); - } - - return npu; -@@ -956,6 +1182,8 @@ static int airoha_ppe_offload_setup(stru - if (err) - goto error_npu_put; - -+ airoha_ppe_foe_flow_stats_reset(eth->ppe, npu); -+ - rcu_assign_pointer(eth->npu, npu); - synchronize_rcu(); - -@@ -1027,6 +1255,15 @@ int airoha_ppe_init(struct airoha_eth *e - if (!ppe->foe_flow) - return -ENOMEM; - -+ foe_size = PPE_STATS_NUM_ENTRIES * sizeof(*ppe->foe_stats); -+ if (foe_size) { -+ ppe->foe_stats = dmam_alloc_coherent(eth->dev, foe_size, -+ &ppe->foe_stats_dma, -+ GFP_KERNEL); -+ if (!ppe->foe_stats) -+ return -ENOMEM; -+ } -+ - err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); - if (err) - return err; ---- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c -@@ -61,6 +61,7 @@ static int airoha_ppe_debugfs_foe_show(s - u16 *src_port = NULL, *dest_port = NULL; - struct airoha_foe_mac_info_common *l2; - unsigned char h_source[ETH_ALEN] = {}; -+ struct airoha_foe_stats64 stats = {}; - unsigned char h_dest[ETH_ALEN]; - struct airoha_foe_entry *hwe; - u32 type, state, ib2, data; -@@ -144,14 +145,18 @@ static int airoha_ppe_debugfs_foe_show(s - cpu_to_be16(hwe->ipv4.l2.src_mac_lo); - } - -+ airoha_ppe_foe_entry_get_stats(ppe, i, &stats); -+ - *((__be32 *)h_dest) = cpu_to_be32(l2->dest_mac_hi); - *((__be16 *)&h_dest[4]) = cpu_to_be16(l2->dest_mac_lo); - *((__be32 *)h_source) = cpu_to_be32(l2->src_mac_hi); - - seq_printf(m, " eth=%pM->%pM etype=%04x data=%08x" -- " vlan=%d,%d ib1=%08x ib2=%08x\n", -+ " vlan=%d,%d ib1=%08x ib2=%08x" -+ " packets=%llu bytes=%llu\n", - h_source, h_dest, l2->etype, data, -- l2->vlan1, l2->vlan2, hwe->ib1, ib2); -+ l2->vlan1, l2->vlan2, hwe->ib1, ib2, -+ stats.packets, stats.bytes); - } - - return 0; diff --git a/target/linux/airoha/patches-6.12/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch b/target/linux/airoha/patches-6.12/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch deleted file mode 100644 index 30c74ddec64..00000000000 --- a/target/linux/airoha/patches-6.12/073-03-v6.16-net-airoha-ppe-Disable-packet-keepalive.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a98326c151ea3d92e9496858cc2dacccd0870941 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 16 May 2025 10:00:01 +0200 -Subject: [PATCH 3/3] net: airoha: ppe: Disable packet keepalive - -Since netfilter flowtable entries are now refreshed by flow-stats -polling, we can disable hw packet keepalive used to periodically send -packets belonging to offloaded flows to the kernel in order to refresh -flowtable entries. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250516-airoha-en7581-flowstats-v2-3-06d5fbf28984@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -84,6 +84,7 @@ static void airoha_ppe_hw_init(struct ai - - airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), - PPE_TB_CFG_SEARCH_MISS_MASK | -+ PPE_TB_CFG_KEEPALIVE_MASK | - PPE_TB_ENTRY_SIZE_MASK, - FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | - FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); diff --git a/target/linux/airoha/patches-6.12/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch b/target/linux/airoha/patches-6.12/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch deleted file mode 100644 index 0a29bb8e00a..00000000000 --- a/target/linux/airoha/patches-6.12/074-01-v6.16-net-airoha-Do-not-store-hfwd-references-in-airoha_qd.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 09aa788f98da3e2f41ce158cc691d6d52e808bc9 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 21 May 2025 09:16:37 +0200 -Subject: [PATCH 1/3] net: airoha: Do not store hfwd references in airoha_qdma - struct - -Since hfwd descriptor and buffer queues are allocated via -dmam_alloc_coherent() we do not need to store their references -in airoha_qdma struct. This patch does not introduce any logical changes, -just code clean-up. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-2-a6e9b085b4f0@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 8 ++------ - drivers/net/ethernet/airoha/airoha_eth.h | 6 ------ - 2 files changed, 2 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1098,17 +1098,13 @@ static int airoha_qdma_init_hfwd_queues( - int size; - - size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); -- qdma->hfwd.desc = dmam_alloc_coherent(eth->dev, size, &dma_addr, -- GFP_KERNEL); -- if (!qdma->hfwd.desc) -+ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) - return -ENOMEM; - - airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); - - size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; -- qdma->hfwd.q = dmam_alloc_coherent(eth->dev, size, &dma_addr, -- GFP_KERNEL); -- if (!qdma->hfwd.q) -+ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) - return -ENOMEM; - - airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -513,12 +513,6 @@ struct airoha_qdma { - - struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; - struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; -- -- /* descriptor and packet buffers for qdma hw forward */ -- struct { -- void *desc; -- void *q; -- } hfwd; - }; - - struct airoha_gdm_port { diff --git a/target/linux/airoha/patches-6.12/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch b/target/linux/airoha/patches-6.12/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch deleted file mode 100644 index e3282ced5f9..00000000000 --- a/target/linux/airoha/patches-6.12/074-02-v6.16-net-airoha-Add-the-capability-to-allocate-hwfd-buffe.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 3a1ce9e3d01bbf3912c3e3f81cb554d558eb715b Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 21 May 2025 09:16:38 +0200 -Subject: [PATCH 2/3] net: airoha: Add the capability to allocate hwfd buffers - via reserved-memory - -In some configurations QDMA blocks require a contiguous block of -system memory for hwfd buffers queue. Introduce the capability to allocate -hw buffers forwarding queue via the reserved-memory DTS property instead of -running dmam_alloc_coherent(). - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-3-a6e9b085b4f0@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 33 +++++++++++++++++++++--- - 1 file changed, 30 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -5,6 +5,7 @@ - */ - #include - #include -+#include - #include - #include - #include -@@ -1093,9 +1094,11 @@ static void airoha_qdma_cleanup_tx_queue - static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) - { - struct airoha_eth *eth = qdma->eth; -+ int id = qdma - ð->qdma[0]; - dma_addr_t dma_addr; -+ const char *name; -+ int size, index; - u32 status; -- int size; - - size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); - if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) -@@ -1103,10 +1106,34 @@ static int airoha_qdma_init_hfwd_queues( - - airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); - -- size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; -- if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) -+ name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); -+ if (!name) - return -ENOMEM; - -+ index = of_property_match_string(eth->dev->of_node, -+ "memory-region-names", name); -+ if (index >= 0) { -+ struct reserved_mem *rmem; -+ struct device_node *np; -+ -+ /* Consume reserved memory for hw forwarding buffers queue if -+ * available in the DTS -+ */ -+ np = of_parse_phandle(eth->dev->of_node, "memory-region", -+ index); -+ if (!np) -+ return -ENODEV; -+ -+ rmem = of_reserved_mem_lookup(np); -+ of_node_put(np); -+ dma_addr = rmem->base; -+ } else { -+ size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; -+ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, -+ GFP_KERNEL)) -+ return -ENOMEM; -+ } -+ - airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); - - airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, diff --git a/target/linux/airoha/patches-6.12/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch b/target/linux/airoha/patches-6.12/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch deleted file mode 100644 index 40d57a48e0e..00000000000 --- a/target/linux/airoha/patches-6.12/074-03-v6.16-net-airoha-Add-the-capability-to-allocate-hfwd-descr.patch +++ /dev/null @@ -1,82 +0,0 @@ -From c683e378c0907e66cee939145edf936c254ff1e3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 21 May 2025 09:16:39 +0200 -Subject: [PATCH 3/3] net: airoha: Add the capability to allocate hfwd - descriptors in SRAM - -In order to improve packet processing and packet forwarding -performances, EN7581 SoC supports consuming SRAM instead of DRAM for -hw forwarding descriptors queue. -For downlink hw accelerated traffic request to consume SRAM memory -for hw forwarding descriptors queue. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250521-airopha-desc-sram-v3-4-a6e9b085b4f0@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 11 +---------- - drivers/net/ethernet/airoha/airoha_eth.h | 9 +++++++++ - drivers/net/ethernet/airoha/airoha_ppe.c | 6 ++++++ - 3 files changed, 16 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -71,15 +71,6 @@ static void airoha_qdma_irq_disable(stru - airoha_qdma_set_irqmask(irq_bank, index, mask, 0); - } - --static bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) --{ -- /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. -- * GDM{2,3,4} can be used as wan port connected to an external -- * phy module. -- */ -- return port->id == 1; --} -- - static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) - { - struct airoha_eth *eth = port->qdma->eth; -@@ -1145,7 +1136,7 @@ static int airoha_qdma_init_hfwd_queues( - LMGR_INIT_START | LMGR_SRAM_MODE_MASK | - HW_FWD_DESC_NUM_MASK, - FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | -- LMGR_INIT_START); -+ LMGR_INIT_START | LMGR_SRAM_MODE_MASK); - - return read_poll_timeout(airoha_qdma_rr, status, - !(status & LMGR_INIT_START), USEC_PER_MSEC, ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -597,6 +597,15 @@ u32 airoha_rmw(void __iomem *base, u32 o - #define airoha_qdma_clear(qdma, offset, val) \ - airoha_rmw((qdma)->regs, (offset), (val), 0) - -+static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) -+{ -+ /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. -+ * GDM{2,3,4} can be used as wan port connected to an external -+ * phy module. -+ */ -+ return port->id == 1; -+} -+ - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -251,6 +251,12 @@ static int airoha_ppe_foe_entry_prepare( - else - pse_port = 2; /* uplink relies on GDM2 loopback */ - val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); -+ -+ /* For downlink traffic consume SRAM memory for hw forwarding -+ * descriptors queue. -+ */ -+ if (airhoa_is_lan_gdm_port(port)) -+ val |= AIROHA_FOE_IB2_FAST_PATH; - } - - if (is_multicast_ether_addr(data->eth.h_dest)) diff --git a/target/linux/airoha/patches-6.12/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch b/target/linux/airoha/patches-6.12/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch deleted file mode 100644 index 4e7fbb72e50..00000000000 --- a/target/linux/airoha/patches-6.12/075-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_allo.patch +++ /dev/null @@ -1,42 +0,0 @@ -From c59783780c8ad66f6076a9a7c74df3e006e29519 Mon Sep 17 00:00:00 2001 -From: Christophe JAILLET -Date: Sat, 24 May 2025 09:29:11 +0200 -Subject: [PATCH] net: airoha: Fix an error handling path in - airoha_alloc_gdm_port() - -If register_netdev() fails, the error handling path of the probe will not -free the memory allocated by the previous airoha_metadata_dst_alloc() call -because port->dev->reg_state will not be NETREG_REGISTERED. - -So, an explicit airoha_metadata_dst_free() call is needed in this case to -avoid a memory leak. - -Fixes: af3cf757d5c9 ("net: airoha: Move DSA tag in DMA descriptor") -Signed-off-by: Christophe JAILLET -Acked-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/1b94b91345017429ed653e2f05d25620dc2823f9.1746715755.git.christophe.jaillet@wanadoo.fr -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2901,7 +2901,15 @@ static int airoha_alloc_gdm_port(struct - if (err) - return err; - -- return register_netdev(dev); -+ err = register_netdev(dev); -+ if (err) -+ goto free_metadata_dst; -+ -+ return 0; -+ -+free_metadata_dst: -+ airoha_metadata_dst_free(port); -+ return err; - } - - static int airoha_probe(struct platform_device *pdev) diff --git a/target/linux/airoha/patches-6.12/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch b/target/linux/airoha/patches-6.12/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch deleted file mode 100644 index 334661dd964..00000000000 --- a/target/linux/airoha/patches-6.12/076-01-v6.16-net-airoha-Initialize-PPE-UPDMEM-source-mac-table.patch +++ /dev/null @@ -1,122 +0,0 @@ -From a869d3a5eb011a9cf9bd864f31f5cf27362de8c7 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 2 Jun 2025 12:55:37 +0200 -Subject: [PATCH 1/3] net: airoha: Initialize PPE UPDMEM source-mac table - -UPDMEM source-mac table is a key-value map used to store devices mac -addresses according to the port identifier. UPDMEM source mac table is -used during IPv6 traffic hw acceleration since PPE entries, for space -constraints, do not contain the full source mac address but just the -identifier in the UPDMEM source-mac table. -Configure UPDMEM source-mac table with device mac addresses and set -the source-mac ID field for PPE IPv6 entries in order to select the -proper device mac address as source mac for L3 IPv6 hw accelerated traffic. - -Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250602-airoha-flowtable-ipv6-fix-v2-1-3287f8b55214@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 2 ++ - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - drivers/net/ethernet/airoha/airoha_ppe.c | 26 ++++++++++++++++++++++- - drivers/net/ethernet/airoha/airoha_regs.h | 10 +++++++++ - 4 files changed, 38 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -84,6 +84,8 @@ static void airoha_set_macaddr(struct ai - val = (addr[3] << 16) | (addr[4] << 8) | addr[5]; - airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); - airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); -+ -+ airoha_ppe_init_upd_mem(port); - } - - static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -614,6 +614,7 @@ void airoha_ppe_check_skb(struct airoha_ - int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data); - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); -+void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash); - void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -223,6 +223,7 @@ static int airoha_ppe_foe_entry_prepare( - int dsa_port = airoha_get_dsa_port(&dev); - struct airoha_foe_mac_info_common *l2; - u32 qdata, ports_pad, val; -+ u8 smac_id = 0xf; - - memset(hwe, 0, sizeof(*hwe)); - -@@ -257,6 +258,8 @@ static int airoha_ppe_foe_entry_prepare( - */ - if (airhoa_is_lan_gdm_port(port)) - val |= AIROHA_FOE_IB2_FAST_PATH; -+ -+ smac_id = port->id; - } - - if (is_multicast_ether_addr(data->eth.h_dest)) -@@ -291,7 +294,7 @@ static int airoha_ppe_foe_entry_prepare( - hwe->ipv4.l2.src_mac_lo = - get_unaligned_be16(data->eth.h_source + 4); - } else { -- l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, 0xf); -+ l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id); - } - - if (data->vlan.num) { -@@ -1238,6 +1241,27 @@ void airoha_ppe_check_skb(struct airoha_ - airoha_ppe_foe_insert_entry(ppe, skb, hash); - } - -+void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port) -+{ -+ struct airoha_eth *eth = port->qdma->eth; -+ struct net_device *dev = port->dev; -+ const u8 *addr = dev->dev_addr; -+ u32 val; -+ -+ val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; -+ airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val); -+ airoha_fe_wr(eth, REG_UPDMEM_CTRL(0), -+ FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) | -+ PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK); -+ -+ val = (addr[0] << 8) | addr[1]; -+ airoha_fe_wr(eth, REG_UPDMEM_DATA(0), val); -+ airoha_fe_wr(eth, REG_UPDMEM_CTRL(0), -+ FIELD_PREP(PPE_UPDMEM_ADDR_MASK, port->id) | -+ FIELD_PREP(PPE_UPDMEM_OFFSET_MASK, 1) | -+ PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK); -+} -+ - int airoha_ppe_init(struct airoha_eth *eth) - { - struct airoha_ppe *ppe; ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -313,6 +313,16 @@ - #define REG_PPE_RAM_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x320) - #define REG_PPE_RAM_ENTRY(_m, _n) (REG_PPE_RAM_BASE(_m) + ((_n) << 2)) - -+#define REG_UPDMEM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x370) -+#define PPE_UPDMEM_ACK_MASK BIT(31) -+#define PPE_UPDMEM_ADDR_MASK GENMASK(11, 8) -+#define PPE_UPDMEM_OFFSET_MASK GENMASK(7, 4) -+#define PPE_UPDMEM_SEL_MASK GENMASK(3, 2) -+#define PPE_UPDMEM_WR_MASK BIT(1) -+#define PPE_UPDMEM_REQ_MASK BIT(0) -+ -+#define REG_UPDMEM_DATA(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x374) -+ - #define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) - #define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) - #define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) diff --git a/target/linux/airoha/patches-6.12/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch b/target/linux/airoha/patches-6.12/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch deleted file mode 100644 index faa7669e0d4..00000000000 --- a/target/linux/airoha/patches-6.12/076-02-v6.16-net-airoha-Fix-IPv6-hw-acceleration-in-bridge-mode.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 504a577c9b000f9e0e99e1b28616fb4eb369e1ef Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 2 Jun 2025 12:55:38 +0200 -Subject: [PATCH 2/3] net: airoha: Fix IPv6 hw acceleration in bridge mode - -ib2 and airoha_foe_mac_info_common have not the same offsets in -airoha_foe_bridge and airoha_foe_ipv6 structures. Current codebase does -not accelerate IPv6 traffic in bridge mode since ib2 and l2 info are not -set properly copying airoha_foe_bridge struct into airoha_foe_ipv6 one -in airoha_ppe_foe_commit_subflow_entry routine. -Fix IPv6 hw acceleration in bridge mode resolving ib2 and -airoha_foe_mac_info_common overwrite in -airoha_ppe_foe_commit_subflow_entry() and configuring them with proper -values. - -Fixes: cd53f622611f ("net: airoha: Add L2 hw acceleration support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250602-airoha-flowtable-ipv6-fix-v2-2-3287f8b55214@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 23 ++++++++++++----------- - 1 file changed, 12 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -639,7 +639,6 @@ airoha_ppe_foe_commit_subflow_entry(stru - u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP; - struct airoha_foe_entry *hwe_p, hwe; - struct airoha_flow_table_entry *f; -- struct airoha_foe_mac_info *l2; - int type; - - hwe_p = airoha_ppe_foe_get_entry(ppe, hash); -@@ -656,18 +655,20 @@ airoha_ppe_foe_commit_subflow_entry(stru - - memcpy(&hwe, hwe_p, sizeof(*hwe_p)); - hwe.ib1 = (hwe.ib1 & mask) | (e->data.ib1 & ~mask); -- l2 = &hwe.bridge.l2; -- memcpy(l2, &e->data.bridge.l2, sizeof(*l2)); - - type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe.ib1); -- if (type == PPE_PKT_TYPE_IPV4_HNAPT) -- memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple, -- sizeof(hwe.ipv4.new_tuple)); -- else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T && -- l2->common.etype == ETH_P_IP) -- l2->common.etype = ETH_P_IPV6; -+ if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { -+ memcpy(&hwe.ipv6.l2, &e->data.bridge.l2, sizeof(hwe.ipv6.l2)); -+ hwe.ipv6.ib2 = e->data.bridge.ib2; -+ } else { -+ memcpy(&hwe.bridge.l2, &e->data.bridge.l2, -+ sizeof(hwe.bridge.l2)); -+ hwe.bridge.ib2 = e->data.bridge.ib2; -+ if (type == PPE_PKT_TYPE_IPV4_HNAPT) -+ memcpy(&hwe.ipv4.new_tuple, &hwe.ipv4.orig_tuple, -+ sizeof(hwe.ipv4.new_tuple)); -+ } - -- hwe.bridge.ib2 = e->data.bridge.ib2; - hwe.bridge.data = e->data.bridge.data; - airoha_ppe_foe_commit_entry(ppe, &hwe, hash); - diff --git a/target/linux/airoha/patches-6.12/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch b/target/linux/airoha/patches-6.12/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch deleted file mode 100644 index f790d9d148c..00000000000 --- a/target/linux/airoha/patches-6.12/076-03-v6.16-net-airoha-Fix-smac_id-configuration-in-bridge-mode.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c86fac5365d3a068422beeb508f2741f1a2d734d Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 2 Jun 2025 12:55:39 +0200 -Subject: [PATCH 3/3] net: airoha: Fix smac_id configuration in bridge mode - -Set PPE entry smac_id field to 0xf in airoha_ppe_foe_commit_subflow_entry -routine for IPv6 traffic in order to instruct the hw to keep original -source mac address for IPv6 hw accelerated traffic in bridge mode. - -Fixes: cd53f622611f ("net: airoha: Add L2 hw acceleration support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250602-airoha-flowtable-ipv6-fix-v2-3-3287f8b55214@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -660,6 +660,11 @@ airoha_ppe_foe_commit_subflow_entry(stru - if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { - memcpy(&hwe.ipv6.l2, &e->data.bridge.l2, sizeof(hwe.ipv6.l2)); - hwe.ipv6.ib2 = e->data.bridge.ib2; -+ /* setting smac_id to 0xf instruct the hw to keep original -+ * source mac address -+ */ -+ hwe.ipv6.l2.src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, -+ 0xf); - } else { - memcpy(&hwe.bridge.l2, &e->data.bridge.l2, - sizeof(hwe.bridge.l2)); diff --git a/target/linux/airoha/patches-6.12/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch b/target/linux/airoha/patches-6.12/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch deleted file mode 100644 index 6245f0d218d..00000000000 --- a/target/linux/airoha/patches-6.12/077-v6.17-net-airoha-Add-PPPoE-offload-support.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0097c4195b1d0ca57d15979626c769c74747b5a0 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 9 Jun 2025 22:28:40 +0200 -Subject: [PATCH] net: airoha: Add PPPoE offload support - -Introduce flowtable hw acceleration for PPPoE traffic. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250609-b4-airoha-flowtable-pppoe-v1-1-1520fa7711b4@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 31 ++++++++++++++++++------ - 1 file changed, 23 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -232,6 +232,7 @@ static int airoha_ppe_foe_entry_prepare( - FIELD_PREP(AIROHA_FOE_IB1_BIND_UDP, l4proto == IPPROTO_UDP) | - FIELD_PREP(AIROHA_FOE_IB1_BIND_VLAN_LAYER, data->vlan.num) | - FIELD_PREP(AIROHA_FOE_IB1_BIND_VPM, data->vlan.num) | -+ FIELD_PREP(AIROHA_FOE_IB1_BIND_PPPOE, data->pppoe.num) | - AIROHA_FOE_IB1_BIND_TTL; - hwe->ib1 = val; - -@@ -281,33 +282,42 @@ static int airoha_ppe_foe_entry_prepare( - hwe->ipv6.data = qdata; - hwe->ipv6.ib2 = val; - l2 = &hwe->ipv6.l2; -+ l2->etype = ETH_P_IPV6; - } else { - hwe->ipv4.data = qdata; - hwe->ipv4.ib2 = val; - l2 = &hwe->ipv4.l2.common; -+ l2->etype = ETH_P_IP; - } - - l2->dest_mac_hi = get_unaligned_be32(data->eth.h_dest); - l2->dest_mac_lo = get_unaligned_be16(data->eth.h_dest + 4); - if (type <= PPE_PKT_TYPE_IPV4_DSLITE) { -+ struct airoha_foe_mac_info *mac_info; -+ - l2->src_mac_hi = get_unaligned_be32(data->eth.h_source); - hwe->ipv4.l2.src_mac_lo = - get_unaligned_be16(data->eth.h_source + 4); -+ -+ mac_info = (struct airoha_foe_mac_info *)l2; -+ mac_info->pppoe_id = data->pppoe.sid; - } else { -- l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id); -+ l2->src_mac_hi = FIELD_PREP(AIROHA_FOE_MAC_SMAC_ID, smac_id) | -+ FIELD_PREP(AIROHA_FOE_MAC_PPPOE_ID, -+ data->pppoe.sid); - } - - if (data->vlan.num) { -- l2->etype = dsa_port >= 0 ? BIT(dsa_port) : 0; - l2->vlan1 = data->vlan.hdr[0].id; - if (data->vlan.num == 2) - l2->vlan2 = data->vlan.hdr[1].id; -- } else if (dsa_port >= 0) { -- l2->etype = BIT(15) | BIT(dsa_port); -- } else if (type >= PPE_PKT_TYPE_IPV6_ROUTE_3T) { -- l2->etype = ETH_P_IPV6; -- } else { -- l2->etype = ETH_P_IP; -+ } -+ -+ if (dsa_port >= 0) { -+ l2->etype = BIT(dsa_port); -+ l2->etype |= !data->vlan.num ? BIT(15) : 0; -+ } else if (data->pppoe.num) { -+ l2->etype = ETH_P_PPP_SES; - } - - return 0; -@@ -957,6 +967,11 @@ static int airoha_ppe_flow_offload_repla - case FLOW_ACTION_VLAN_POP: - break; - case FLOW_ACTION_PPPOE_PUSH: -+ if (data.pppoe.num == 1 || data.vlan.num == 2) -+ return -EOPNOTSUPP; -+ -+ data.pppoe.sid = act->pppoe.sid; -+ data.pppoe.num++; - break; - default: - return -EOPNOTSUPP; diff --git a/target/linux/airoha/patches-6.12/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch b/target/linux/airoha/patches-6.12/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch deleted file mode 100644 index 1550c592612..00000000000 --- a/target/linux/airoha/patches-6.12/078-v6.16-net-airoha-Enable-RX-queues-16-31.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f478d68b653323b691280b40fbd3b8ca1ac75aa2 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 9 Jun 2025 22:40:35 +0200 -Subject: [PATCH] net: airoha: Enable RX queues 16-31 - -Fix RX_DONE_INT_MASK definition in order to enable RX queues 16-31. - -Fixes: f252493e18353 ("net: airoha: Enable multiple IRQ lines support in airoha_eth driver.") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250609-aioha-fix-rx-queue-mask-v1-1-f33706a06fa2@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_regs.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -614,8 +614,9 @@ - RX19_DONE_INT_MASK | RX18_DONE_INT_MASK | \ - RX17_DONE_INT_MASK | RX16_DONE_INT_MASK) - --#define RX_DONE_INT_MASK (RX_DONE_HIGH_INT_MASK | RX_DONE_LOW_INT_MASK) - #define RX_DONE_HIGH_OFFSET fls(RX_DONE_HIGH_INT_MASK) -+#define RX_DONE_INT_MASK \ -+ ((RX_DONE_HIGH_INT_MASK << RX_DONE_HIGH_OFFSET) | RX_DONE_LOW_INT_MASK) - - #define INT_RX2_MASK(_n) \ - ((RX_NO_CPU_DSCP_HIGH_INT_MASK & (_n)) | \ diff --git a/target/linux/airoha/patches-6.12/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch b/target/linux/airoha/patches-6.12/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch deleted file mode 100644 index 551e8e3c9d8..00000000000 --- a/target/linux/airoha/patches-6.12/079-v6.16-net-airoha-Always-check-return-value-from-airoha_ppe.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 78bd03ee1f20a267d2c218884b66041b3508ac9c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 18 Jun 2025 09:37:40 +0200 -Subject: [PATCH] net: airoha: Always check return value from - airoha_ppe_foe_get_entry() - -airoha_ppe_foe_get_entry routine can return NULL, so check the returned -pointer is not NULL in airoha_ppe_foe_flow_l2_entry_update() - -Fixes: b81e0f2b58be3 ("net: airoha: Add FLOW_CLS_STATS callback support") -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250618-check-ret-from-airoha_ppe_foe_get_entry-v2-1-068dcea3cc66@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -819,8 +819,10 @@ airoha_ppe_foe_flow_l2_entry_update(stru - int idle; - - hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); -- ib1 = READ_ONCE(hwe->ib1); -+ if (!hwe) -+ continue; - -+ ib1 = READ_ONCE(hwe->ib1); - state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, ib1); - if (state != AIROHA_FOE_STATE_BIND) { - iter->hash = 0xffff; diff --git a/target/linux/airoha/patches-6.12/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch b/target/linux/airoha/patches-6.12/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch deleted file mode 100644 index 6744be00111..00000000000 --- a/target/linux/airoha/patches-6.12/080-01-v6.16-net-airoha-Compute-number-of-descriptors-according-t.patch +++ /dev/null @@ -1,77 +0,0 @@ -From edf8afeecfbb0b8c1a2edb8c8892d2f759d35321 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 19 Jun 2025 09:07:24 +0200 -Subject: [PATCH 1/2] net: airoha: Compute number of descriptors according to - reserved memory size - -In order to not exceed the reserved memory size for hwfd buffers, -compute the number of hwfd buffers/descriptors according to the -reserved memory size and the size of each hwfd buffer (2KB). - -Fixes: 3a1ce9e3d01b ("net: airoha: Add the capability to allocate hwfd buffers via reserved-memory") -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250619-airoha-hw-num-desc-v4-1-49600a9b319a@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1086,19 +1086,13 @@ static void airoha_qdma_cleanup_tx_queue - - static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma) - { -+ int size, index, num_desc = HW_DSCP_NUM; - struct airoha_eth *eth = qdma->eth; - int id = qdma - ð->qdma[0]; - dma_addr_t dma_addr; - const char *name; -- int size, index; - u32 status; - -- size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc); -- if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) -- return -ENOMEM; -- -- airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); -- - name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); - if (!name) - return -ENOMEM; -@@ -1120,8 +1114,12 @@ static int airoha_qdma_init_hfwd_queues( - rmem = of_reserved_mem_lookup(np); - of_node_put(np); - dma_addr = rmem->base; -+ /* Compute the number of hw descriptors according to the -+ * reserved memory size and the payload buffer size -+ */ -+ num_desc = rmem->size / AIROHA_MAX_PACKET_SIZE; - } else { -- size = AIROHA_MAX_PACKET_SIZE * HW_DSCP_NUM; -+ size = AIROHA_MAX_PACKET_SIZE * num_desc; - if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, - GFP_KERNEL)) - return -ENOMEM; -@@ -1129,6 +1127,11 @@ static int airoha_qdma_init_hfwd_queues( - - airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr); - -+ size = num_desc * sizeof(struct airoha_qdma_fwd_desc); -+ if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL)) -+ return -ENOMEM; -+ -+ airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); - airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, - HW_FWD_DSCP_PAYLOAD_SIZE_MASK, - FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); -@@ -1137,7 +1140,7 @@ static int airoha_qdma_init_hfwd_queues( - airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, - LMGR_INIT_START | LMGR_SRAM_MODE_MASK | - HW_FWD_DESC_NUM_MASK, -- FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) | -+ FIELD_PREP(HW_FWD_DESC_NUM_MASK, num_desc) | - LMGR_INIT_START | LMGR_SRAM_MODE_MASK); - - return read_poll_timeout(airoha_qdma_rr, status, diff --git a/target/linux/airoha/patches-6.12/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch b/target/linux/airoha/patches-6.12/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch deleted file mode 100644 index 77199281446..00000000000 --- a/target/linux/airoha/patches-6.12/080-02-v6.16-net-airoha-Differentiate-hwfd-buffer-size-for-QDMA0-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 7b46bdaec00a675f6fac9d0b01a2105b5746ebe9 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 19 Jun 2025 09:07:25 +0200 -Subject: [PATCH 2/2] net: airoha: Differentiate hwfd buffer size for QDMA0 and - QDMA1 - -EN7581 SoC allows configuring the size and the number of buffers in -hwfd payload queue for both QDMA0 and QDMA1. -In order to reduce the required DRAM used for hwfd buffers queues and -decrease the memory footprint, differentiate hwfd buffer size for QDMA0 -and QDMA1 and reduce hwfd buffer size to 1KB for QDMA1 (WAN) while -maintaining 2KB for QDMA0 (LAN). - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250619-airoha-hw-num-desc-v4-2-49600a9b319a@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1089,14 +1089,15 @@ static int airoha_qdma_init_hfwd_queues( - int size, index, num_desc = HW_DSCP_NUM; - struct airoha_eth *eth = qdma->eth; - int id = qdma - ð->qdma[0]; -+ u32 status, buf_size; - dma_addr_t dma_addr; - const char *name; -- u32 status; - - name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id); - if (!name) - return -ENOMEM; - -+ buf_size = id ? AIROHA_MAX_PACKET_SIZE / 2 : AIROHA_MAX_PACKET_SIZE; - index = of_property_match_string(eth->dev->of_node, - "memory-region-names", name); - if (index >= 0) { -@@ -1117,9 +1118,9 @@ static int airoha_qdma_init_hfwd_queues( - /* Compute the number of hw descriptors according to the - * reserved memory size and the payload buffer size - */ -- num_desc = rmem->size / AIROHA_MAX_PACKET_SIZE; -+ num_desc = div_u64(rmem->size, buf_size); - } else { -- size = AIROHA_MAX_PACKET_SIZE * num_desc; -+ size = buf_size * num_desc; - if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, - GFP_KERNEL)) - return -ENOMEM; -@@ -1132,9 +1133,10 @@ static int airoha_qdma_init_hfwd_queues( - return -ENOMEM; - - airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr); -+ /* QDMA0: 2KB. QDMA1: 1KB */ - airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG, - HW_FWD_DSCP_PAYLOAD_SIZE_MASK, -- FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0)); -+ FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, !!id)); - airoha_qdma_rmw(qdma, REG_FWD_DSCP_LOW_THR, FWD_DSCP_LOW_THR_MASK, - FIELD_PREP(FWD_DSCP_LOW_THR_MASK, 128)); - airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG, diff --git a/target/linux/airoha/patches-6.12/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch b/target/linux/airoha/patches-6.12/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch deleted file mode 100644 index 919b6b44da0..00000000000 --- a/target/linux/airoha/patches-6.12/081-v6.17-net-airoha-Fix-PPE-table-access-in-airoha_ppe_debugf.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 38358fa3cc8e16c6862a3e5c5c233f9f652e3a6d Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 31 Jul 2025 12:29:08 +0200 -Subject: [PATCH] net: airoha: Fix PPE table access in - airoha_ppe_debugfs_foe_show() - -In order to avoid any possible race we need to hold the ppe_lock -spinlock accessing the hw PPE table. airoha_ppe_foe_get_entry routine is -always executed holding ppe_lock except in airoha_ppe_debugfs_foe_show -routine. Fix the problem introducing airoha_ppe_foe_get_entry_locked -routine. - -Fixes: 3fe15c640f380 ("net: airoha: Introduce PPE debugfs support") -Reviewed-by: Dawid Osuchowski -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250731-airoha_ppe_foe_get_entry_locked-v2-1-50efbd8c0fd6@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 26 ++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -508,9 +508,11 @@ static void airoha_ppe_foe_flow_stats_up - FIELD_PREP(AIROHA_FOE_IB2_NBQ, nbq); - } - --struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, -- u32 hash) -+static struct airoha_foe_entry * -+airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash) - { -+ lockdep_assert_held(&ppe_lock); -+ - if (hash < PPE_SRAM_NUM_ENTRIES) { - u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); - struct airoha_eth *eth = ppe->eth; -@@ -537,6 +539,18 @@ struct airoha_foe_entry *airoha_ppe_foe_ - return ppe->foe + hash * sizeof(struct airoha_foe_entry); - } - -+struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, -+ u32 hash) -+{ -+ struct airoha_foe_entry *hwe; -+ -+ spin_lock_bh(&ppe_lock); -+ hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); -+ spin_unlock_bh(&ppe_lock); -+ -+ return hwe; -+} -+ - static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e, - struct airoha_foe_entry *hwe) - { -@@ -651,7 +665,7 @@ airoha_ppe_foe_commit_subflow_entry(stru - struct airoha_flow_table_entry *f; - int type; - -- hwe_p = airoha_ppe_foe_get_entry(ppe, hash); -+ hwe_p = airoha_ppe_foe_get_entry_locked(ppe, hash); - if (!hwe_p) - return -EINVAL; - -@@ -703,7 +717,7 @@ static void airoha_ppe_foe_insert_entry( - - spin_lock_bh(&ppe_lock); - -- hwe = airoha_ppe_foe_get_entry(ppe, hash); -+ hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); - if (!hwe) - goto unlock; - -@@ -818,7 +832,7 @@ airoha_ppe_foe_flow_l2_entry_update(stru - u32 ib1, state; - int idle; - -- hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); -+ hwe = airoha_ppe_foe_get_entry_locked(ppe, iter->hash); - if (!hwe) - continue; - -@@ -855,7 +869,7 @@ static void airoha_ppe_foe_flow_entry_up - if (e->hash == 0xffff) - goto unlock; - -- hwe_p = airoha_ppe_foe_get_entry(ppe, e->hash); -+ hwe_p = airoha_ppe_foe_get_entry_locked(ppe, e->hash); - if (!hwe_p) - goto unlock; - diff --git a/target/linux/airoha/patches-6.12/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch b/target/linux/airoha/patches-6.12/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch deleted file mode 100644 index eda914aab71..00000000000 --- a/target/linux/airoha/patches-6.12/082-v6.17-net-airoha-ppe-Do-not-invalid-PPE-entries-in-case-of.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 9f6b606b6b37e61427412708411e8e04b1a858e8 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 18 Aug 2025 11:58:25 +0200 -Subject: [PATCH] net: airoha: ppe: Do not invalid PPE entries in case of SW - hash collision - -SW hash computed by airoha_ppe_foe_get_entry_hash routine (used for -foe_flow hlist) can theoretically produce collisions between two -different HW PPE entries. -In airoha_ppe_foe_insert_entry() if the collision occurs we will mark -the second PPE entry in the list as stale (setting the hw hash to 0xffff). -Stale entries are no more updated in airoha_ppe_foe_flow_entry_update -routine and so they are removed by Netfilter. -Fix the problem not marking the second entry as stale in -airoha_ppe_foe_insert_entry routine if we have already inserted the -brand new entry in the PPE table and let Netfilter remove real stale -entries according to their timestamp. -Please note this is just a theoretical issue spotted reviewing the code -and not faced running the system. - -Fixes: cd53f622611f9 ("net: airoha: Add L2 hw acceleration support") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250818-airoha-en7581-hash-collision-fix-v1-1-d190c4b53d1c@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -736,10 +736,8 @@ static void airoha_ppe_foe_insert_entry( - continue; - } - -- if (commit_done || !airoha_ppe_foe_compare_entry(e, hwe)) { -- e->hash = 0xffff; -+ if (!airoha_ppe_foe_compare_entry(e, hwe)) - continue; -- } - - airoha_ppe_foe_commit_entry(ppe, &e->data, hash); - commit_done = true; diff --git a/target/linux/airoha/patches-6.12/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch b/target/linux/airoha/patches-6.12/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch deleted file mode 100644 index 7e9e9423ec2..00000000000 --- a/target/linux/airoha/patches-6.12/084-01-v6.18-net-airoha-npu-Add-NPU-wlan-memory-initialization-co.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 564923b02c1d2fe02ee789f9849ff79979b63b9f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 11 Aug 2025 17:31:37 +0200 -Subject: [PATCH 1/6] net: airoha: npu: Add NPU wlan memory initialization - commands - -Introduce wlan_init_reserved_memory callback used by MT76 driver during -NPU wlan offloading setup. -This is a preliminary patch to enable wlan flowtable offload for EN7581 -SoC with MT76 driver. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-2-58823603bb4e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 82 ++++++++++++++++++++++++ - drivers/net/ethernet/airoha/airoha_npu.h | 38 +++++++++++ - 2 files changed, 120 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -124,6 +124,13 @@ struct ppe_mbox_data { - }; - }; - -+struct wlan_mbox_data { -+ u32 ifindex:4; -+ u32 func_type:4; -+ u32 func_id; -+ DECLARE_FLEX_ARRAY(u8, d); -+}; -+ - static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id, - void *p, int size) - { -@@ -390,6 +397,80 @@ out: - return err; - } - -+static int airoha_npu_wlan_msg_send(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_set_cmd func_id, -+ void *data, int data_len, gfp_t gfp) -+{ -+ struct wlan_mbox_data *wlan_data; -+ int err, len; -+ -+ len = sizeof(*wlan_data) + data_len; -+ wlan_data = kzalloc(len, gfp); -+ if (!wlan_data) -+ return -ENOMEM; -+ -+ wlan_data->ifindex = ifindex; -+ wlan_data->func_type = NPU_OP_SET; -+ wlan_data->func_id = func_id; -+ memcpy(wlan_data->d, data, data_len); -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, len); -+ kfree(wlan_data); -+ -+ return err; -+} -+ -+static int -+airoha_npu_wlan_set_reserved_memory(struct airoha_npu *npu, -+ int ifindex, const char *name, -+ enum airoha_npu_wlan_set_cmd func_id) -+{ -+ struct device *dev = npu->dev; -+ struct resource res; -+ int err; -+ u32 val; -+ -+ err = of_reserved_mem_region_to_resource_byname(dev->of_node, name, -+ &res); -+ if (err) -+ return err; -+ -+ val = res.start; -+ return airoha_npu_wlan_msg_send(npu, ifindex, func_id, &val, -+ sizeof(val), GFP_KERNEL); -+} -+ -+static int airoha_npu_wlan_init_memory(struct airoha_npu *npu) -+{ -+ enum airoha_npu_wlan_set_cmd cmd = WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU; -+ u32 val = 0; -+ int err; -+ -+ err = airoha_npu_wlan_msg_send(npu, 1, cmd, &val, sizeof(val), -+ GFP_KERNEL); -+ if (err) -+ return err; -+ -+ cmd = WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR; -+ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-bufid", cmd); -+ if (err) -+ return err; -+ -+ cmd = WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR; -+ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "pkt", cmd); -+ if (err) -+ return err; -+ -+ cmd = WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR; -+ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "tx-pkt", cmd); -+ if (err) -+ return err; -+ -+ cmd = WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU; -+ return airoha_npu_wlan_msg_send(npu, 0, cmd, &val, sizeof(val), -+ GFP_KERNEL); -+} -+ - struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) - { - struct platform_device *pdev; -@@ -493,6 +574,7 @@ static int airoha_npu_probe(struct platf - npu->ops.ppe_deinit = airoha_npu_ppe_deinit; - npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; - npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; -+ npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; - - npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); - if (IS_ERR(npu->regmap)) ---- a/drivers/net/ethernet/airoha/airoha_npu.h -+++ b/drivers/net/ethernet/airoha/airoha_npu.h -@@ -6,6 +6,43 @@ - - #define NPU_NUM_CORES 8 - -+enum airoha_npu_wlan_set_cmd { -+ WLAN_FUNC_SET_WAIT_PCIE_ADDR, -+ WLAN_FUNC_SET_WAIT_DESC, -+ WLAN_FUNC_SET_WAIT_NPU_INIT_DONE, -+ WLAN_FUNC_SET_WAIT_TRAN_TO_CPU, -+ WLAN_FUNC_SET_WAIT_BA_WIN_SIZE, -+ WLAN_FUNC_SET_WAIT_DRIVER_MODEL, -+ WLAN_FUNC_SET_WAIT_DEL_STA, -+ WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR, -+ WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR, -+ WLAN_FUNC_SET_WAIT_IS_TEST_NOBA, -+ WLAN_FUNC_SET_WAIT_FLUSHONE_TIMEOUT, -+ WLAN_FUNC_SET_WAIT_FLUSHALL_TIMEOUT, -+ WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU, -+ WLAN_FUNC_SET_WAIT_PCIE_STATE, -+ WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, -+ WLAN_FUNC_SET_WAIT_ERROR_RETRY_TIMES, -+ WLAN_FUNC_SET_WAIT_BAR_INFO, -+ WLAN_FUNC_SET_WAIT_FAST_FLAG, -+ WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU, -+ WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, -+ WLAN_FUNC_SET_WAIT_TX_DESC_HW_BASE, -+ WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, -+ WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, -+ WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR, -+ WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, -+ WLAN_FUNC_SET_WAIT_INODE_DEBUG_FLAG, -+ WLAN_FUNC_SET_WAIT_INODE_HW_CFG_INFO, -+ WLAN_FUNC_SET_WAIT_INODE_STOP_ACTION, -+ WLAN_FUNC_SET_WAIT_INODE_PCIE_SWAP, -+ WLAN_FUNC_SET_WAIT_RATELIMIT_CTRL, -+ WLAN_FUNC_SET_WAIT_HWNAT_INIT, -+ WLAN_FUNC_SET_WAIT_ARHT_CHIP_INFO, -+ WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR, -+ WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, -+}; -+ - struct airoha_npu { - struct device *dev; - struct regmap *regmap; -@@ -29,6 +66,7 @@ struct airoha_npu { - dma_addr_t foe_addr, - u32 entry_size, u32 hash, - bool ppe2); -+ int (*wlan_init_reserved_memory)(struct airoha_npu *npu); - } ops; - }; - diff --git a/target/linux/airoha/patches-6.12/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch b/target/linux/airoha/patches-6.12/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch deleted file mode 100644 index 5ff820d0be9..00000000000 --- a/target/linux/airoha/patches-6.12/084-02-v6.18-net-airoha-npu-Add-wlan_-send-get-_msg-NPU-callbacks.patch +++ /dev/null @@ -1,139 +0,0 @@ -From f97fc66185b2004ad5f393f78b3e645009ddd1d0 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 11 Aug 2025 17:31:38 +0200 -Subject: [PATCH 2/6] net: airoha: npu: Add wlan_{send,get}_msg NPU callbacks - -Introduce wlan_send_msg() and wlan_get_msg() NPU wlan callbacks used -by the wlan driver (MT76) to initialize NPU module registers in order to -offload wireless-wired traffic. -This is a preliminary patch to enable wlan flowtable offload for EN7581 -SoC with MT76 driver. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-3-58823603bb4e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 52 ++++++++++++++++++++++++ - drivers/net/ethernet/airoha/airoha_npu.h | 22 ++++++++++ - 2 files changed, 74 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -42,6 +42,22 @@ - #define REG_CR_MBQ8_CTRL(_n) (NPU_MBOX_BASE_ADDR + 0x0b0 + ((_n) << 2)) - #define REG_CR_NPU_MIB(_n) (NPU_MBOX_BASE_ADDR + 0x140 + ((_n) << 2)) - -+#define NPU_WLAN_BASE_ADDR 0x30d000 -+ -+#define REG_IRQ_STATUS (NPU_WLAN_BASE_ADDR + 0x030) -+#define REG_IRQ_RXDONE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 2) + 0x034) -+#define NPU_IRQ_RX_MASK(_n) ((_n) == 1 ? BIT(17) : BIT(16)) -+ -+#define REG_TX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x080) -+#define REG_TX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x084) -+#define REG_TX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x088) -+#define REG_TX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x08c) -+ -+#define REG_RX_BASE(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x180) -+#define REG_RX_DSCP_NUM(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x184) -+#define REG_RX_CPU_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x188) -+#define REG_RX_DMA_IDX(_n) (NPU_WLAN_BASE_ADDR + ((_n) << 4) + 0x18c) -+ - #define NPU_TIMER_BASE_ADDR 0x310100 - #define REG_WDT_TIMER_CTRL(_n) (NPU_TIMER_BASE_ADDR + ((_n) * 0x100)) - #define WDT_EN_MASK BIT(25) -@@ -420,6 +436,30 @@ static int airoha_npu_wlan_msg_send(stru - return err; - } - -+static int airoha_npu_wlan_msg_get(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_get_cmd func_id, -+ void *data, int data_len, gfp_t gfp) -+{ -+ struct wlan_mbox_data *wlan_data; -+ int err, len; -+ -+ len = sizeof(*wlan_data) + data_len; -+ wlan_data = kzalloc(len, gfp); -+ if (!wlan_data) -+ return -ENOMEM; -+ -+ wlan_data->ifindex = ifindex; -+ wlan_data->func_type = NPU_OP_GET; -+ wlan_data->func_id = func_id; -+ -+ err = airoha_npu_send_msg(npu, NPU_FUNC_WIFI, wlan_data, len); -+ if (!err) -+ memcpy(data, wlan_data->d, data_len); -+ kfree(wlan_data); -+ -+ return err; -+} -+ - static int - airoha_npu_wlan_set_reserved_memory(struct airoha_npu *npu, - int ifindex, const char *name, -@@ -471,6 +511,15 @@ static int airoha_npu_wlan_init_memory(s - GFP_KERNEL); - } - -+static u32 airoha_npu_wlan_queue_addr_get(struct airoha_npu *npu, int qid, -+ bool xmit) -+{ -+ if (xmit) -+ return REG_TX_BASE(qid + 2); -+ -+ return REG_RX_BASE(qid); -+} -+ - struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) - { - struct platform_device *pdev; -@@ -575,6 +624,9 @@ static int airoha_npu_probe(struct platf - npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; - npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; - npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; -+ npu->ops.wlan_send_msg = airoha_npu_wlan_msg_send; -+ npu->ops.wlan_get_msg = airoha_npu_wlan_msg_get; -+ npu->ops.wlan_get_queue_addr = airoha_npu_wlan_queue_addr_get; - - npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); - if (IS_ERR(npu->regmap)) ---- a/drivers/net/ethernet/airoha/airoha_npu.h -+++ b/drivers/net/ethernet/airoha/airoha_npu.h -@@ -43,6 +43,20 @@ enum airoha_npu_wlan_set_cmd { - WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, - }; - -+enum airoha_npu_wlan_get_cmd { -+ WLAN_FUNC_GET_WAIT_NPU_INFO, -+ WLAN_FUNC_GET_WAIT_LAST_RATE, -+ WLAN_FUNC_GET_WAIT_COUNTER, -+ WLAN_FUNC_GET_WAIT_DBG_COUNTER, -+ WLAN_FUNC_GET_WAIT_RXDESC_BASE, -+ WLAN_FUNC_GET_WAIT_WCID_DBG_COUNTER, -+ WLAN_FUNC_GET_WAIT_DMA_ADDR, -+ WLAN_FUNC_GET_WAIT_RING_SIZE, -+ WLAN_FUNC_GET_WAIT_NPU_SUPPORT_MAP, -+ WLAN_FUNC_GET_WAIT_MDC_LOCK_ADDRESS, -+ WLAN_FUNC_GET_WAIT_NPU_VERSION, -+}; -+ - struct airoha_npu { - struct device *dev; - struct regmap *regmap; -@@ -67,6 +81,14 @@ struct airoha_npu { - u32 entry_size, u32 hash, - bool ppe2); - int (*wlan_init_reserved_memory)(struct airoha_npu *npu); -+ int (*wlan_send_msg)(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_set_cmd func_id, -+ void *data, int data_len, gfp_t gfp); -+ int (*wlan_get_msg)(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_get_cmd func_id, -+ void *data, int data_len, gfp_t gfp); -+ u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, -+ bool xmit); - } ops; - }; - diff --git a/target/linux/airoha/patches-6.12/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch b/target/linux/airoha/patches-6.12/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch deleted file mode 100644 index f05b947cecd..00000000000 --- a/target/linux/airoha/patches-6.12/084-03-v6.18-net-airoha-npu-Add-wlan-irq-management-callbacks.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 03b7ca3ee5e1b700c462aed5b6cb88f616d6ba7f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 11 Aug 2025 17:31:39 +0200 -Subject: [PATCH 3/6] net: airoha: npu: Add wlan irq management callbacks - -Introduce callbacks used by the MT76 driver to configure NPU SoC -interrupts. This is a preliminary patch to enable wlan flowtable -offload for EN7581 SoC with MT76 driver. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-4-58823603bb4e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 27 ++++++++++++++++++++++++ - drivers/net/ethernet/airoha/airoha_npu.h | 4 ++++ - 2 files changed, 31 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -520,6 +520,29 @@ static u32 airoha_npu_wlan_queue_addr_ge - return REG_RX_BASE(qid); - } - -+static void airoha_npu_wlan_irq_status_set(struct airoha_npu *npu, u32 val) -+{ -+ regmap_write(npu->regmap, REG_IRQ_STATUS, val); -+} -+ -+static u32 airoha_npu_wlan_irq_status_get(struct airoha_npu *npu, int q) -+{ -+ u32 val; -+ -+ regmap_read(npu->regmap, REG_IRQ_STATUS, &val); -+ return val; -+} -+ -+static void airoha_npu_wlan_irq_enable(struct airoha_npu *npu, int q) -+{ -+ regmap_set_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); -+} -+ -+static void airoha_npu_wlan_irq_disable(struct airoha_npu *npu, int q) -+{ -+ regmap_clear_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); -+} -+ - struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) - { - struct platform_device *pdev; -@@ -627,6 +650,10 @@ static int airoha_npu_probe(struct platf - npu->ops.wlan_send_msg = airoha_npu_wlan_msg_send; - npu->ops.wlan_get_msg = airoha_npu_wlan_msg_get; - npu->ops.wlan_get_queue_addr = airoha_npu_wlan_queue_addr_get; -+ npu->ops.wlan_set_irq_status = airoha_npu_wlan_irq_status_set; -+ npu->ops.wlan_get_irq_status = airoha_npu_wlan_irq_status_get; -+ npu->ops.wlan_enable_irq = airoha_npu_wlan_irq_enable; -+ npu->ops.wlan_disable_irq = airoha_npu_wlan_irq_disable; - - npu->regmap = devm_regmap_init_mmio(dev, base, ®map_config); - if (IS_ERR(npu->regmap)) ---- a/drivers/net/ethernet/airoha/airoha_npu.h -+++ b/drivers/net/ethernet/airoha/airoha_npu.h -@@ -89,6 +89,10 @@ struct airoha_npu { - void *data, int data_len, gfp_t gfp); - u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, - bool xmit); -+ void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); -+ u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); -+ void (*wlan_enable_irq)(struct airoha_npu *npu, int q); -+ void (*wlan_disable_irq)(struct airoha_npu *npu, int q); - } ops; - }; - diff --git a/target/linux/airoha/patches-6.12/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch b/target/linux/airoha/patches-6.12/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch deleted file mode 100644 index 234dc8b99ae..00000000000 --- a/target/linux/airoha/patches-6.12/084-04-v6.18-net-airoha-npu-Read-NPU-wlan-interrupt-lines-from-th.patch +++ /dev/null @@ -1,58 +0,0 @@ -From a1740b16c83729d908c760eaa821f27b51e58a13 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 11 Aug 2025 17:31:40 +0200 -Subject: [PATCH 4/6] net: airoha: npu: Read NPU wlan interrupt lines from the - DTS - -Read all NPU wlan IRQ lines from the NPU device-tree node. -NPU module fires wlan irq lines when the traffic to/from the WiFi NIC is -not hw accelerated (these interrupts will be consumed by the MT76 driver -in subsequent patches). -This is a preliminary patch to enable wlan flowtable offload for EN7581 -SoC. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-5-58823603bb4e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 9 +++++++++ - drivers/net/ethernet/airoha/airoha_npu.h | 3 +++ - 2 files changed, 12 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -696,6 +696,15 @@ static int airoha_npu_probe(struct platf - INIT_WORK(&core->wdt_work, airoha_npu_wdt_work); - } - -+ /* wlan IRQ lines */ -+ for (i = 0; i < ARRAY_SIZE(npu->irqs); i++) { -+ irq = platform_get_irq(pdev, i + ARRAY_SIZE(npu->cores) + 1); -+ if (irq < 0) -+ return irq; -+ -+ npu->irqs[i] = irq; -+ } -+ - err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - if (err) - return err; ---- a/drivers/net/ethernet/airoha/airoha_npu.h -+++ b/drivers/net/ethernet/airoha/airoha_npu.h -@@ -5,6 +5,7 @@ - */ - - #define NPU_NUM_CORES 8 -+#define NPU_NUM_IRQ 6 - - enum airoha_npu_wlan_set_cmd { - WLAN_FUNC_SET_WAIT_PCIE_ADDR, -@@ -68,6 +69,8 @@ struct airoha_npu { - struct work_struct wdt_work; - } cores[NPU_NUM_CORES]; - -+ int irqs[NPU_NUM_IRQ]; -+ - struct airoha_foe_stats __iomem *stats; - - struct { diff --git a/target/linux/airoha/patches-6.12/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch b/target/linux/airoha/patches-6.12/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch deleted file mode 100644 index c285af23c32..00000000000 --- a/target/linux/airoha/patches-6.12/084-05-v6.18-net-airoha-npu-Enable-core-3-for-WiFi-offloading.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 29c4a3ce508961a02d185ead2d52699b16d82c6d Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 11 Aug 2025 17:31:41 +0200 -Subject: [PATCH 5/6] net: airoha: npu: Enable core 3 for WiFi offloading - -NPU core 3 is responsible for WiFi offloading so enable it during NPU -probe. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-6-58823603bb4e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -726,8 +726,7 @@ static int airoha_npu_probe(struct platf - usleep_range(1000, 2000); - - /* enable NPU cores */ -- /* do not start core3 since it is used for WiFi offloading */ -- regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xf7); -+ regmap_write(npu->regmap, REG_CR_BOOT_CONFIG, 0xff); - regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); - msleep(100); - diff --git a/target/linux/airoha/patches-6.12/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch b/target/linux/airoha/patches-6.12/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch deleted file mode 100644 index ef98c85c366..00000000000 --- a/target/linux/airoha/patches-6.12/084-06-v6.18-net-airoha-Add-airoha_offload.h-header.patch +++ /dev/null @@ -1,416 +0,0 @@ -From b3ef7bdec66fb1813e865fd39d179a93cefd2015 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 11 Aug 2025 17:31:42 +0200 -Subject: [PATCH 6/6] net: airoha: Add airoha_offload.h header - -Move NPU definitions to airoha_offload.h in include/linux/soc/airoha/ in -order to allow the MT76 driver to access the callback definitions. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250811-airoha-en7581-wlan-offlaod-v7-7-58823603bb4e@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 2 +- - drivers/net/ethernet/airoha/airoha_npu.h | 103 --------- - drivers/net/ethernet/airoha/airoha_ppe.c | 2 +- - include/linux/soc/airoha/airoha_offload.h | 260 ++++++++++++++++++++++ - 4 files changed, 262 insertions(+), 105 deletions(-) - delete mode 100644 drivers/net/ethernet/airoha/airoha_npu.h - create mode 100644 include/linux/soc/airoha/airoha_offload.h - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -11,9 +11,9 @@ - #include - #include - #include -+#include - - #include "airoha_eth.h" --#include "airoha_npu.h" - - #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" - #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" ---- a/drivers/net/ethernet/airoha/airoha_npu.h -+++ /dev/null -@@ -1,103 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ --/* -- * Copyright (c) 2025 AIROHA Inc -- * Author: Lorenzo Bianconi -- */ -- --#define NPU_NUM_CORES 8 --#define NPU_NUM_IRQ 6 -- --enum airoha_npu_wlan_set_cmd { -- WLAN_FUNC_SET_WAIT_PCIE_ADDR, -- WLAN_FUNC_SET_WAIT_DESC, -- WLAN_FUNC_SET_WAIT_NPU_INIT_DONE, -- WLAN_FUNC_SET_WAIT_TRAN_TO_CPU, -- WLAN_FUNC_SET_WAIT_BA_WIN_SIZE, -- WLAN_FUNC_SET_WAIT_DRIVER_MODEL, -- WLAN_FUNC_SET_WAIT_DEL_STA, -- WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR, -- WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR, -- WLAN_FUNC_SET_WAIT_IS_TEST_NOBA, -- WLAN_FUNC_SET_WAIT_FLUSHONE_TIMEOUT, -- WLAN_FUNC_SET_WAIT_FLUSHALL_TIMEOUT, -- WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU, -- WLAN_FUNC_SET_WAIT_PCIE_STATE, -- WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, -- WLAN_FUNC_SET_WAIT_ERROR_RETRY_TIMES, -- WLAN_FUNC_SET_WAIT_BAR_INFO, -- WLAN_FUNC_SET_WAIT_FAST_FLAG, -- WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU, -- WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, -- WLAN_FUNC_SET_WAIT_TX_DESC_HW_BASE, -- WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, -- WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, -- WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR, -- WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, -- WLAN_FUNC_SET_WAIT_INODE_DEBUG_FLAG, -- WLAN_FUNC_SET_WAIT_INODE_HW_CFG_INFO, -- WLAN_FUNC_SET_WAIT_INODE_STOP_ACTION, -- WLAN_FUNC_SET_WAIT_INODE_PCIE_SWAP, -- WLAN_FUNC_SET_WAIT_RATELIMIT_CTRL, -- WLAN_FUNC_SET_WAIT_HWNAT_INIT, -- WLAN_FUNC_SET_WAIT_ARHT_CHIP_INFO, -- WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR, -- WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, --}; -- --enum airoha_npu_wlan_get_cmd { -- WLAN_FUNC_GET_WAIT_NPU_INFO, -- WLAN_FUNC_GET_WAIT_LAST_RATE, -- WLAN_FUNC_GET_WAIT_COUNTER, -- WLAN_FUNC_GET_WAIT_DBG_COUNTER, -- WLAN_FUNC_GET_WAIT_RXDESC_BASE, -- WLAN_FUNC_GET_WAIT_WCID_DBG_COUNTER, -- WLAN_FUNC_GET_WAIT_DMA_ADDR, -- WLAN_FUNC_GET_WAIT_RING_SIZE, -- WLAN_FUNC_GET_WAIT_NPU_SUPPORT_MAP, -- WLAN_FUNC_GET_WAIT_MDC_LOCK_ADDRESS, -- WLAN_FUNC_GET_WAIT_NPU_VERSION, --}; -- --struct airoha_npu { -- struct device *dev; -- struct regmap *regmap; -- -- struct airoha_npu_core { -- struct airoha_npu *npu; -- /* protect concurrent npu memory accesses */ -- spinlock_t lock; -- struct work_struct wdt_work; -- } cores[NPU_NUM_CORES]; -- -- int irqs[NPU_NUM_IRQ]; -- -- struct airoha_foe_stats __iomem *stats; -- -- struct { -- int (*ppe_init)(struct airoha_npu *npu); -- int (*ppe_deinit)(struct airoha_npu *npu); -- int (*ppe_flush_sram_entries)(struct airoha_npu *npu, -- dma_addr_t foe_addr, -- int sram_num_entries); -- int (*ppe_foe_commit_entry)(struct airoha_npu *npu, -- dma_addr_t foe_addr, -- u32 entry_size, u32 hash, -- bool ppe2); -- int (*wlan_init_reserved_memory)(struct airoha_npu *npu); -- int (*wlan_send_msg)(struct airoha_npu *npu, int ifindex, -- enum airoha_npu_wlan_set_cmd func_id, -- void *data, int data_len, gfp_t gfp); -- int (*wlan_get_msg)(struct airoha_npu *npu, int ifindex, -- enum airoha_npu_wlan_get_cmd func_id, -- void *data, int data_len, gfp_t gfp); -- u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, -- bool xmit); -- void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); -- u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); -- void (*wlan_enable_irq)(struct airoha_npu *npu, int q); -- void (*wlan_disable_irq)(struct airoha_npu *npu, int q); -- } ops; --}; -- --struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); --void airoha_npu_put(struct airoha_npu *npu); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -7,10 +7,10 @@ - #include - #include - #include -+#include - #include - #include - --#include "airoha_npu.h" - #include "airoha_regs.h" - #include "airoha_eth.h" - ---- /dev/null -+++ b/include/linux/soc/airoha/airoha_offload.h -@@ -0,0 +1,260 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2025 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+#ifndef AIROHA_OFFLOAD_H -+#define AIROHA_OFFLOAD_H -+ -+#include -+#include -+ -+#define NPU_NUM_CORES 8 -+#define NPU_NUM_IRQ 6 -+#define NPU_RX0_DESC_NUM 512 -+#define NPU_RX1_DESC_NUM 512 -+ -+/* CTRL */ -+#define NPU_RX_DMA_DESC_LAST_MASK BIT(29) -+#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(28, 15) -+#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(14, 1) -+#define NPU_RX_DMA_DESC_DONE_MASK BIT(0) -+/* INFO */ -+#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 28) -+#define NPU_RX_DMA_PKT_ID_MASK GENMASK(28, 26) -+#define NPU_RX_DMA_SRC_PORT_MASK GENMASK(25, 21) -+#define NPU_RX_DMA_CRSN_MASK GENMASK(20, 16) -+#define NPU_RX_DMA_FOE_ID_MASK GENMASK(15, 0) -+/* DATA */ -+#define NPU_RX_DMA_SID_MASK GENMASK(31, 16) -+#define NPU_RX_DMA_FRAG_TYPE_MASK GENMASK(15, 14) -+#define NPU_RX_DMA_PRIORITY_MASK GENMASK(13, 10) -+#define NPU_RX_DMA_RADIO_ID_MASK GENMASK(9, 6) -+#define NPU_RX_DMA_VAP_ID_MASK GENMASK(5, 2) -+#define NPU_RX_DMA_FRAME_TYPE_MASK GENMASK(1, 0) -+ -+struct airoha_npu_rx_dma_desc { -+ u32 ctrl; -+ u32 info; -+ u32 data; -+ u32 addr; -+ u64 rsv; -+} __packed; -+ -+/* CTRL */ -+#define NPU_TX_DMA_DESC_SCHED_MASK BIT(31) -+#define NPU_TX_DMA_DESC_LEN_MASK GENMASK(30, 18) -+#define NPU_TX_DMA_DESC_VEND_LEN_MASK GENMASK(17, 1) -+#define NPU_TX_DMA_DESC_DONE_MASK BIT(0) -+ -+#define NPU_TXWI_LEN 192 -+ -+struct airoha_npu_tx_dma_desc { -+ u32 ctrl; -+ u32 addr; -+ u64 rsv; -+ u8 txwi[NPU_TXWI_LEN]; -+} __packed; -+ -+enum airoha_npu_wlan_set_cmd { -+ WLAN_FUNC_SET_WAIT_PCIE_ADDR, -+ WLAN_FUNC_SET_WAIT_DESC, -+ WLAN_FUNC_SET_WAIT_NPU_INIT_DONE, -+ WLAN_FUNC_SET_WAIT_TRAN_TO_CPU, -+ WLAN_FUNC_SET_WAIT_BA_WIN_SIZE, -+ WLAN_FUNC_SET_WAIT_DRIVER_MODEL, -+ WLAN_FUNC_SET_WAIT_DEL_STA, -+ WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR, -+ WLAN_FUNC_SET_WAIT_PKT_BUF_ADDR, -+ WLAN_FUNC_SET_WAIT_IS_TEST_NOBA, -+ WLAN_FUNC_SET_WAIT_FLUSHONE_TIMEOUT, -+ WLAN_FUNC_SET_WAIT_FLUSHALL_TIMEOUT, -+ WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU, -+ WLAN_FUNC_SET_WAIT_PCIE_STATE, -+ WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, -+ WLAN_FUNC_SET_WAIT_ERROR_RETRY_TIMES, -+ WLAN_FUNC_SET_WAIT_BAR_INFO, -+ WLAN_FUNC_SET_WAIT_FAST_FLAG, -+ WLAN_FUNC_SET_WAIT_NPU_BAND0_ONCPU, -+ WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, -+ WLAN_FUNC_SET_WAIT_TX_DESC_HW_BASE, -+ WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, -+ WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, -+ WLAN_FUNC_SET_WAIT_TX_PKT_BUF_ADDR, -+ WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, -+ WLAN_FUNC_SET_WAIT_INODE_DEBUG_FLAG, -+ WLAN_FUNC_SET_WAIT_INODE_HW_CFG_INFO, -+ WLAN_FUNC_SET_WAIT_INODE_STOP_ACTION, -+ WLAN_FUNC_SET_WAIT_INODE_PCIE_SWAP, -+ WLAN_FUNC_SET_WAIT_RATELIMIT_CTRL, -+ WLAN_FUNC_SET_WAIT_HWNAT_INIT, -+ WLAN_FUNC_SET_WAIT_ARHT_CHIP_INFO, -+ WLAN_FUNC_SET_WAIT_TX_BUF_CHECK_ADDR, -+ WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, -+}; -+ -+enum airoha_npu_wlan_get_cmd { -+ WLAN_FUNC_GET_WAIT_NPU_INFO, -+ WLAN_FUNC_GET_WAIT_LAST_RATE, -+ WLAN_FUNC_GET_WAIT_COUNTER, -+ WLAN_FUNC_GET_WAIT_DBG_COUNTER, -+ WLAN_FUNC_GET_WAIT_RXDESC_BASE, -+ WLAN_FUNC_GET_WAIT_WCID_DBG_COUNTER, -+ WLAN_FUNC_GET_WAIT_DMA_ADDR, -+ WLAN_FUNC_GET_WAIT_RING_SIZE, -+ WLAN_FUNC_GET_WAIT_NPU_SUPPORT_MAP, -+ WLAN_FUNC_GET_WAIT_MDC_LOCK_ADDRESS, -+ WLAN_FUNC_GET_WAIT_NPU_VERSION, -+}; -+ -+struct airoha_npu { -+#if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) -+ struct device *dev; -+ struct regmap *regmap; -+ -+ struct airoha_npu_core { -+ struct airoha_npu *npu; -+ /* protect concurrent npu memory accesses */ -+ spinlock_t lock; -+ struct work_struct wdt_work; -+ } cores[NPU_NUM_CORES]; -+ -+ int irqs[NPU_NUM_IRQ]; -+ -+ struct airoha_foe_stats __iomem *stats; -+ -+ struct { -+ int (*ppe_init)(struct airoha_npu *npu); -+ int (*ppe_deinit)(struct airoha_npu *npu); -+ int (*ppe_flush_sram_entries)(struct airoha_npu *npu, -+ dma_addr_t foe_addr, -+ int sram_num_entries); -+ int (*ppe_foe_commit_entry)(struct airoha_npu *npu, -+ dma_addr_t foe_addr, -+ u32 entry_size, u32 hash, -+ bool ppe2); -+ int (*wlan_init_reserved_memory)(struct airoha_npu *npu); -+ int (*wlan_send_msg)(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_set_cmd func_id, -+ void *data, int data_len, gfp_t gfp); -+ int (*wlan_get_msg)(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_get_cmd func_id, -+ void *data, int data_len, gfp_t gfp); -+ u32 (*wlan_get_queue_addr)(struct airoha_npu *npu, int qid, -+ bool xmit); -+ void (*wlan_set_irq_status)(struct airoha_npu *npu, u32 val); -+ u32 (*wlan_get_irq_status)(struct airoha_npu *npu, int q); -+ void (*wlan_enable_irq)(struct airoha_npu *npu, int q); -+ void (*wlan_disable_irq)(struct airoha_npu *npu, int q); -+ } ops; -+#endif -+}; -+ -+#if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) -+struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); -+void airoha_npu_put(struct airoha_npu *npu); -+ -+static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) -+{ -+ return npu->ops.wlan_init_reserved_memory(npu); -+} -+ -+static inline int airoha_npu_wlan_send_msg(struct airoha_npu *npu, -+ int ifindex, -+ enum airoha_npu_wlan_set_cmd cmd, -+ void *data, int data_len, gfp_t gfp) -+{ -+ return npu->ops.wlan_send_msg(npu, ifindex, cmd, data, data_len, gfp); -+} -+ -+static inline int airoha_npu_wlan_get_msg(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_get_cmd cmd, -+ void *data, int data_len, gfp_t gfp) -+{ -+ return npu->ops.wlan_get_msg(npu, ifindex, cmd, data, data_len, gfp); -+} -+ -+static inline u32 airoha_npu_wlan_get_queue_addr(struct airoha_npu *npu, -+ int qid, bool xmit) -+{ -+ return npu->ops.wlan_get_queue_addr(npu, qid, xmit); -+} -+ -+static inline void airoha_npu_wlan_set_irq_status(struct airoha_npu *npu, -+ u32 val) -+{ -+ npu->ops.wlan_set_irq_status(npu, val); -+} -+ -+static inline u32 airoha_npu_wlan_get_irq_status(struct airoha_npu *npu, int q) -+{ -+ return npu->ops.wlan_get_irq_status(npu, q); -+} -+ -+static inline void airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) -+{ -+ npu->ops.wlan_enable_irq(npu, q); -+} -+ -+static inline void airoha_npu_wlan_disable_irq(struct airoha_npu *npu, int q) -+{ -+ npu->ops.wlan_disable_irq(npu, q); -+} -+#else -+static inline struct airoha_npu *airoha_npu_get(struct device *dev, -+ dma_addr_t *foe_stats_addr) -+{ -+ return NULL; -+} -+ -+static inline void airoha_npu_put(struct airoha_npu *npu) -+{ -+} -+ -+static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int airoha_npu_wlan_send_msg(struct airoha_npu *npu, -+ int ifindex, -+ enum airoha_npu_wlan_set_cmd cmd, -+ void *data, int data_len, gfp_t gfp) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int airoha_npu_wlan_get_msg(struct airoha_npu *npu, int ifindex, -+ enum airoha_npu_wlan_get_cmd cmd, -+ void *data, int data_len, gfp_t gfp) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline u32 airoha_npu_wlan_get_queue_addr(struct airoha_npu *npu, -+ int qid, bool xmit) -+{ -+ return 0; -+} -+ -+static inline void airoha_npu_wlan_set_irq_status(struct airoha_npu *npu, -+ u32 val) -+{ -+} -+ -+static inline u32 airoha_npu_wlan_get_irq_status(struct airoha_npu *npu, -+ int q) -+{ -+ return 0; -+} -+ -+static inline void airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) -+{ -+} -+ -+static inline void airoha_npu_wlan_disable_irq(struct airoha_npu *npu, int q) -+{ -+} -+#endif -+ -+#endif /* AIROHA_OFFLOAD_H */ diff --git a/target/linux/airoha/patches-6.12/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch b/target/linux/airoha/patches-6.12/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch deleted file mode 100644 index ab9a3761a50..00000000000 --- a/target/linux/airoha/patches-6.12/085-v6.18-net-airoha-Add-wlan-flowtable-TX-offload.patch +++ /dev/null @@ -1,198 +0,0 @@ -From a8bdd935d1ddb7186358fb60ffe84253e85340c8 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 14 Aug 2025 09:51:16 +0200 -Subject: [PATCH] net: airoha: Add wlan flowtable TX offload - -Introduce support to offload the traffic received on the ethernet NIC -and forwarded to the wireless one using HW Packet Processor Engine (PPE) -capabilities. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250814-airoha-en7581-wlan-tx-offload-v1-1-72e0a312003e@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.h | 11 +++ - drivers/net/ethernet/airoha/airoha_ppe.c | 103 ++++++++++++++++------- - 2 files changed, 85 insertions(+), 29 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -252,6 +252,10 @@ enum { - #define AIROHA_FOE_MAC_SMAC_ID GENMASK(20, 16) - #define AIROHA_FOE_MAC_PPPOE_ID GENMASK(15, 0) - -+#define AIROHA_FOE_MAC_WDMA_QOS GENMASK(15, 12) -+#define AIROHA_FOE_MAC_WDMA_BAND BIT(11) -+#define AIROHA_FOE_MAC_WDMA_WCID GENMASK(10, 0) -+ - struct airoha_foe_mac_info_common { - u16 vlan1; - u16 etype; -@@ -481,6 +485,13 @@ struct airoha_flow_table_entry { - unsigned long cookie; - }; - -+struct airoha_wdma_info { -+ u8 idx; -+ u8 queue; -+ u16 wcid; -+ u8 bss; -+}; -+ - /* RX queue to IRQ mapping: BIT(q) in IRQ(n) */ - #define RX_IRQ0_BANK_PIN_MASK 0x839f - #define RX_IRQ1_BANK_PIN_MASK 0x7fe00000 ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -190,6 +190,31 @@ static int airoha_ppe_flow_mangle_ipv4(c - return 0; - } - -+static int airoha_ppe_get_wdma_info(struct net_device *dev, const u8 *addr, -+ struct airoha_wdma_info *info) -+{ -+ struct net_device_path_stack stack; -+ struct net_device_path *path; -+ int err; -+ -+ if (!dev) -+ return -ENODEV; -+ -+ err = dev_fill_forward_path(dev, addr, &stack); -+ if (err) -+ return err; -+ -+ path = &stack.path[stack.num_paths - 1]; -+ if (path->type != DEV_PATH_MTK_WDMA) -+ return -1; -+ -+ info->idx = path->mtk_wdma.wdma_idx; -+ info->bss = path->mtk_wdma.bss; -+ info->wcid = path->mtk_wdma.wcid; -+ -+ return 0; -+} -+ - static int airoha_get_dsa_port(struct net_device **dev) - { - #if IS_ENABLED(CONFIG_NET_DSA) -@@ -220,9 +245,9 @@ static int airoha_ppe_foe_entry_prepare( - struct airoha_flow_data *data, - int l4proto) - { -- int dsa_port = airoha_get_dsa_port(&dev); -+ u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val; -+ int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev); - struct airoha_foe_mac_info_common *l2; -- u32 qdata, ports_pad, val; - u8 smac_id = 0xf; - - memset(hwe, 0, sizeof(*hwe)); -@@ -236,31 +261,47 @@ static int airoha_ppe_foe_entry_prepare( - AIROHA_FOE_IB1_BIND_TTL; - hwe->ib1 = val; - -- val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f) | -- AIROHA_FOE_IB2_PSE_QOS; -- if (dsa_port >= 0) -- val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port); -- -+ val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); - if (dev) { -- struct airoha_gdm_port *port = netdev_priv(dev); -- u8 pse_port; -- -- if (!airoha_is_valid_gdm_port(eth, port)) -- return -EINVAL; -+ struct airoha_wdma_info info = {}; - -- if (dsa_port >= 0) -- pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; -- else -- pse_port = 2; /* uplink relies on GDM2 loopback */ -- val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port); -- -- /* For downlink traffic consume SRAM memory for hw forwarding -- * descriptors queue. -- */ -- if (airhoa_is_lan_gdm_port(port)) -- val |= AIROHA_FOE_IB2_FAST_PATH; -+ if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) { -+ val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) | -+ FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, -+ FE_PSE_PORT_CDM4); -+ qdata |= FIELD_PREP(AIROHA_FOE_ACTDP, info.bss); -+ wlan_etype = FIELD_PREP(AIROHA_FOE_MAC_WDMA_BAND, -+ info.idx) | -+ FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID, -+ info.wcid); -+ } else { -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ u8 pse_port; -+ -+ if (!airoha_is_valid_gdm_port(eth, port)) -+ return -EINVAL; -+ -+ if (dsa_port >= 0) -+ pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 -+ : port->id; -+ else -+ pse_port = 2; /* uplink relies on GDM2 -+ * loopback -+ */ -+ -+ val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port) | -+ AIROHA_FOE_IB2_PSE_QOS; -+ /* For downlink traffic consume SRAM memory for hw -+ * forwarding descriptors queue. -+ */ -+ if (airhoa_is_lan_gdm_port(port)) -+ val |= AIROHA_FOE_IB2_FAST_PATH; -+ if (dsa_port >= 0) -+ val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, -+ dsa_port); - -- smac_id = port->id; -+ smac_id = port->id; -+ } - } - - if (is_multicast_ether_addr(data->eth.h_dest)) -@@ -272,7 +313,6 @@ static int airoha_ppe_foe_entry_prepare( - if (type == PPE_PKT_TYPE_IPV6_ROUTE_3T) - hwe->ipv6.ports = ports_pad; - -- qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f); - if (type == PPE_PKT_TYPE_BRIDGE) { - airoha_ppe_foe_set_bridge_addrs(&hwe->bridge, &data->eth); - hwe->bridge.data = qdata; -@@ -313,7 +353,9 @@ static int airoha_ppe_foe_entry_prepare( - l2->vlan2 = data->vlan.hdr[1].id; - } - -- if (dsa_port >= 0) { -+ if (wlan_etype >= 0) { -+ l2->etype = wlan_etype; -+ } else if (dsa_port >= 0) { - l2->etype = BIT(dsa_port); - l2->etype |= !data->vlan.num ? BIT(15) : 0; - } else if (data->pppoe.num) { -@@ -490,6 +532,10 @@ static void airoha_ppe_foe_flow_stats_up - meter = &hwe->ipv4.l2.meter; - } - -+ pse_port = FIELD_GET(AIROHA_FOE_IB2_PSE_PORT, *ib2); -+ if (pse_port == FE_PSE_PORT_CDM4) -+ return; -+ - airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, index); - - val = FIELD_GET(AIROHA_FOE_CHANNEL | AIROHA_FOE_QID, *data); -@@ -500,7 +546,6 @@ static void airoha_ppe_foe_flow_stats_up - AIROHA_FOE_IB2_PSE_QOS | AIROHA_FOE_IB2_FAST_PATH); - *meter |= FIELD_PREP(AIROHA_FOE_TUNNEL_MTU, val); - -- pse_port = FIELD_GET(AIROHA_FOE_IB2_PSE_PORT, *ib2); - nbq = pse_port == 1 ? 6 : 5; - *ib2 &= ~(AIROHA_FOE_IB2_NBQ | AIROHA_FOE_IB2_PSE_PORT | - AIROHA_FOE_IB2_PSE_QOS); diff --git a/target/linux/airoha/patches-6.12/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch b/target/linux/airoha/patches-6.12/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch deleted file mode 100644 index cef2922869d..00000000000 --- a/target/linux/airoha/patches-6.12/086-01-v6.18-net-airoha-Rely-on-airoha_eth-struct-in-airoha_ppe_f.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 524a43c3a0c17fa0a1223eea36751dcba55e5530 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 23 Aug 2025 09:56:02 +0200 -Subject: [PATCH 1/3] net: airoha: Rely on airoha_eth struct in - airoha_ppe_flow_offload_cmd signature - -Rely on airoha_eth struct in airoha_ppe_flow_offload_cmd routine -signature and in all the called subroutines. -This is a preliminary patch to introduce flowtable offload for traffic -received by the wlan NIC and forwarded to the ethernet one. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250823-airoha-en7581-wlan-rx-offload-v3-1-f78600ec3ed8@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 20 ++++++++------------ - 1 file changed, 8 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -935,11 +935,10 @@ static int airoha_ppe_entry_idle_time(st - return airoha_ppe_get_entry_idle_time(ppe, e->data.ib1); - } - --static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, -+static int airoha_ppe_flow_offload_replace(struct airoha_eth *eth, - struct flow_cls_offload *f) - { - struct flow_rule *rule = flow_cls_offload_flow_rule(f); -- struct airoha_eth *eth = port->qdma->eth; - struct airoha_flow_table_entry *e; - struct airoha_flow_data data = {}; - struct net_device *odev = NULL; -@@ -1136,10 +1135,9 @@ free_entry: - return err; - } - --static int airoha_ppe_flow_offload_destroy(struct airoha_gdm_port *port, -+static int airoha_ppe_flow_offload_destroy(struct airoha_eth *eth, - struct flow_cls_offload *f) - { -- struct airoha_eth *eth = port->qdma->eth; - struct airoha_flow_table_entry *e; - - e = rhashtable_lookup(ð->flow_table, &f->cookie, -@@ -1182,10 +1180,9 @@ void airoha_ppe_foe_entry_get_stats(stru - rcu_read_unlock(); - } - --static int airoha_ppe_flow_offload_stats(struct airoha_gdm_port *port, -+static int airoha_ppe_flow_offload_stats(struct airoha_eth *eth, - struct flow_cls_offload *f) - { -- struct airoha_eth *eth = port->qdma->eth; - struct airoha_flow_table_entry *e; - u32 idle; - -@@ -1209,16 +1206,16 @@ static int airoha_ppe_flow_offload_stats - return 0; - } - --static int airoha_ppe_flow_offload_cmd(struct airoha_gdm_port *port, -+static int airoha_ppe_flow_offload_cmd(struct airoha_eth *eth, - struct flow_cls_offload *f) - { - switch (f->command) { - case FLOW_CLS_REPLACE: -- return airoha_ppe_flow_offload_replace(port, f); -+ return airoha_ppe_flow_offload_replace(eth, f); - case FLOW_CLS_DESTROY: -- return airoha_ppe_flow_offload_destroy(port, f); -+ return airoha_ppe_flow_offload_destroy(eth, f); - case FLOW_CLS_STATS: -- return airoha_ppe_flow_offload_stats(port, f); -+ return airoha_ppe_flow_offload_stats(eth, f); - default: - break; - } -@@ -1288,7 +1285,6 @@ error_npu_put: - int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data) - { - struct airoha_gdm_port *port = netdev_priv(dev); -- struct flow_cls_offload *cls = type_data; - struct airoha_eth *eth = port->qdma->eth; - int err = 0; - -@@ -1297,7 +1293,7 @@ int airoha_ppe_setup_tc_block_cb(struct - if (!eth->npu) - err = airoha_ppe_offload_setup(eth); - if (!err) -- err = airoha_ppe_flow_offload_cmd(port, cls); -+ err = airoha_ppe_flow_offload_cmd(eth, type_data); - - mutex_unlock(&flow_offload_mutex); - diff --git a/target/linux/airoha/patches-6.12/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch b/target/linux/airoha/patches-6.12/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch deleted file mode 100644 index c10fc8bf351..00000000000 --- a/target/linux/airoha/patches-6.12/086-02-v6.18-net-airoha-Add-airoha_ppe_dev-struct-definition.patch +++ /dev/null @@ -1,223 +0,0 @@ -From f45fc18b6de04483643e8aa2ab97737abfe03d59 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 23 Aug 2025 09:56:03 +0200 -Subject: [PATCH 2/3] net: airoha: Add airoha_ppe_dev struct definition - -Introduce airoha_ppe_dev struct as container for PPE offload callbacks -consumed by the MT76 driver during flowtable offload for traffic -received by the wlan NIC and forwarded to the wired one. -Add airoha_ppe_setup_tc_block_cb routine to PPE offload ops for MT76 -driver. -Rely on airoha_ppe_dev pointer in airoha_ppe_setup_tc_block_cb -signature. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250823-airoha-en7581-wlan-rx-offload-v3-2-f78600ec3ed8@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 4 +- - drivers/net/ethernet/airoha/airoha_eth.h | 4 +- - drivers/net/ethernet/airoha/airoha_npu.c | 1 - - drivers/net/ethernet/airoha/airoha_ppe.c | 67 +++++++++++++++++++++-- - include/linux/soc/airoha/airoha_offload.h | 35 ++++++++++++ - 5 files changed, 104 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2622,13 +2622,15 @@ static int airoha_dev_setup_tc_block_cb( - void *type_data, void *cb_priv) - { - struct net_device *dev = cb_priv; -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_eth *eth = port->qdma->eth; - - if (!tc_can_offload(dev)) - return -EOPNOTSUPP; - - switch (type) { - case TC_SETUP_CLSFLOWER: -- return airoha_ppe_setup_tc_block_cb(dev, type_data); -+ return airoha_ppe_setup_tc_block_cb(ð->ppe->dev, type_data); - case TC_SETUP_CLSMATCHALL: - return airoha_dev_tc_matchall(dev, type_data); - default: ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - - #define AIROHA_MAX_NUM_GDM_PORTS 4 -@@ -546,6 +547,7 @@ struct airoha_gdm_port { - #define AIROHA_RXD4_FOE_ENTRY GENMASK(15, 0) - - struct airoha_ppe { -+ struct airoha_ppe_dev dev; - struct airoha_eth *eth; - - void *foe; -@@ -622,7 +624,7 @@ bool airoha_is_valid_gdm_port(struct air - - void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, - u16 hash); --int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data); -+int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); - void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -11,7 +11,6 @@ - #include - #include - #include --#include - - #include "airoha_eth.h" - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -6,8 +6,9 @@ - - #include - #include -+#include -+#include - #include --#include - #include - #include - -@@ -1282,10 +1283,10 @@ error_npu_put: - return err; - } - --int airoha_ppe_setup_tc_block_cb(struct net_device *dev, void *type_data) -+int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_ppe *ppe = dev->priv; -+ struct airoha_eth *eth = ppe->eth; - int err = 0; - - mutex_lock(&flow_offload_mutex); -@@ -1338,6 +1339,61 @@ void airoha_ppe_init_upd_mem(struct airo - PPE_UPDMEM_WR_MASK | PPE_UPDMEM_REQ_MASK); - } - -+struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev) -+{ -+ struct platform_device *pdev; -+ struct device_node *np; -+ struct airoha_eth *eth; -+ -+ np = of_parse_phandle(dev->of_node, "airoha,eth", 0); -+ if (!np) -+ return ERR_PTR(-ENODEV); -+ -+ pdev = of_find_device_by_node(np); -+ if (!pdev) { -+ dev_err(dev, "cannot find device node %s\n", np->name); -+ of_node_put(np); -+ return ERR_PTR(-ENODEV); -+ } -+ of_node_put(np); -+ -+ if (!try_module_get(THIS_MODULE)) { -+ dev_err(dev, "failed to get the device driver module\n"); -+ goto error_pdev_put; -+ } -+ -+ eth = platform_get_drvdata(pdev); -+ if (!eth) -+ goto error_module_put; -+ -+ if (!device_link_add(dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER)) { -+ dev_err(&pdev->dev, -+ "failed to create device link to consumer %s\n", -+ dev_name(dev)); -+ goto error_module_put; -+ } -+ -+ return ð->ppe->dev; -+ -+error_module_put: -+ module_put(THIS_MODULE); -+error_pdev_put: -+ platform_device_put(pdev); -+ -+ return ERR_PTR(-ENODEV); -+} -+EXPORT_SYMBOL_GPL(airoha_ppe_get_dev); -+ -+void airoha_ppe_put_dev(struct airoha_ppe_dev *dev) -+{ -+ struct airoha_ppe *ppe = dev->priv; -+ struct airoha_eth *eth = ppe->eth; -+ -+ module_put(THIS_MODULE); -+ put_device(eth->dev); -+} -+EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); -+ - int airoha_ppe_init(struct airoha_eth *eth) - { - struct airoha_ppe *ppe; -@@ -1347,6 +1403,9 @@ int airoha_ppe_init(struct airoha_eth *e - if (!ppe) - return -ENOMEM; - -+ ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb; -+ ppe->dev.priv = ppe; -+ - foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); - ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, - GFP_KERNEL); ---- a/include/linux/soc/airoha/airoha_offload.h -+++ b/include/linux/soc/airoha/airoha_offload.h -@@ -9,6 +9,41 @@ - #include - #include - -+struct airoha_ppe_dev { -+ struct { -+ int (*setup_tc_block_cb)(struct airoha_ppe_dev *dev, -+ void *type_data); -+ } ops; -+ -+ void *priv; -+}; -+ -+#if (IS_BUILTIN(CONFIG_NET_AIROHA) || IS_MODULE(CONFIG_NET_AIROHA)) -+struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev); -+void airoha_ppe_put_dev(struct airoha_ppe_dev *dev); -+ -+static inline int airoha_ppe_dev_setup_tc_block_cb(struct airoha_ppe_dev *dev, -+ void *type_data) -+{ -+ return dev->ops.setup_tc_block_cb(dev, type_data); -+} -+#else -+static inline struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev) -+{ -+ return NULL; -+} -+ -+static inline void airoha_ppe_put_dev(struct airoha_ppe_dev *dev) -+{ -+} -+ -+static inline int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, -+ void *type_data) -+{ -+ return -EOPNOTSUPP; -+} -+#endif -+ - #define NPU_NUM_CORES 8 - #define NPU_NUM_IRQ 6 - #define NPU_RX0_DESC_NUM 512 diff --git a/target/linux/airoha/patches-6.12/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch b/target/linux/airoha/patches-6.12/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch deleted file mode 100644 index 1edc2aa54c4..00000000000 --- a/target/linux/airoha/patches-6.12/086-03-v6.18-net-airoha-Introduce-check_skb-callback-in-ppe_dev-o.patch +++ /dev/null @@ -1,207 +0,0 @@ -From a7cc1aa151e3a9c0314b995f06102f7763d3bd71 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 23 Aug 2025 09:56:04 +0200 -Subject: [PATCH 3/3] net: airoha: Introduce check_skb callback in ppe_dev ops - -Export airoha_ppe_check_skb routine in ppe_dev ops. check_skb callback -will be used by the MT76 driver in order to offload the traffic received -by the wlan NIC and forwarded to the ethernet one. -Add rx_wlan parameter to airoha_ppe_check_skb routine signature. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20250823-airoha-en7581-wlan-rx-offload-v3-3-f78600ec3ed8@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 3 ++- - drivers/net/ethernet/airoha/airoha_eth.h | 8 ++------ - drivers/net/ethernet/airoha/airoha_ppe.c | 25 +++++++++++++---------- - include/linux/soc/airoha/airoha_offload.h | 20 ++++++++++++++++++ - 4 files changed, 38 insertions(+), 18 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -703,7 +703,8 @@ static int airoha_qdma_rx_process(struct - - reason = FIELD_GET(AIROHA_RXD4_PPE_CPU_REASON, msg1); - if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -- airoha_ppe_check_skb(eth->ppe, q->skb, hash); -+ airoha_ppe_check_skb(ð->ppe->dev, q->skb, hash, -+ false); - - done++; - napi_gro_receive(&q->napi, q->skb); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -230,10 +230,6 @@ struct airoha_hw_stats { - }; - - enum { -- PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, --}; -- --enum { - AIROHA_FOE_STATE_INVALID, - AIROHA_FOE_STATE_UNBIND, - AIROHA_FOE_STATE_BIND, -@@ -622,8 +618,8 @@ static inline bool airhoa_is_lan_gdm_por - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - --void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, -- u16 hash); -+void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, -+ u16 hash, bool rx_wlan); - int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -616,7 +616,7 @@ static bool airoha_ppe_foe_compare_entry - - static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, - struct airoha_foe_entry *e, -- u32 hash) -+ u32 hash, bool rx_wlan) - { - struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); - u32 ts = airoha_ppe_get_timestamp(ppe); -@@ -639,7 +639,8 @@ static int airoha_ppe_foe_commit_entry(s - goto unlock; - } - -- airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); -+ if (!rx_wlan) -+ airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); - - if (hash < PPE_SRAM_NUM_ENTRIES) { - dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); -@@ -665,7 +666,7 @@ static void airoha_ppe_foe_remove_flow(s - e->data.ib1 &= ~AIROHA_FOE_IB1_BIND_STATE; - e->data.ib1 |= FIELD_PREP(AIROHA_FOE_IB1_BIND_STATE, - AIROHA_FOE_STATE_INVALID); -- airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash); -+ airoha_ppe_foe_commit_entry(ppe, &e->data, e->hash, false); - e->hash = 0xffff; - } - if (e->type == FLOW_TYPE_L2_SUBFLOW) { -@@ -704,7 +705,7 @@ static void airoha_ppe_foe_flow_remove_e - static int - airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe, - struct airoha_flow_table_entry *e, -- u32 hash) -+ u32 hash, bool rx_wlan) - { - u32 mask = AIROHA_FOE_IB1_BIND_PACKET_TYPE | AIROHA_FOE_IB1_BIND_UDP; - struct airoha_foe_entry *hwe_p, hwe; -@@ -745,14 +746,14 @@ airoha_ppe_foe_commit_subflow_entry(stru - } - - hwe.bridge.data = e->data.bridge.data; -- airoha_ppe_foe_commit_entry(ppe, &hwe, hash); -+ airoha_ppe_foe_commit_entry(ppe, &hwe, hash, rx_wlan); - - return 0; - } - - static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, - struct sk_buff *skb, -- u32 hash) -+ u32 hash, bool rx_wlan) - { - struct airoha_flow_table_entry *e; - struct airoha_foe_bridge br = {}; -@@ -785,7 +786,7 @@ static void airoha_ppe_foe_insert_entry( - if (!airoha_ppe_foe_compare_entry(e, hwe)) - continue; - -- airoha_ppe_foe_commit_entry(ppe, &e->data, hash); -+ airoha_ppe_foe_commit_entry(ppe, &e->data, hash, rx_wlan); - commit_done = true; - e->hash = hash; - } -@@ -797,7 +798,7 @@ static void airoha_ppe_foe_insert_entry( - e = rhashtable_lookup_fast(&ppe->l2_flows, &br, - airoha_l2_flow_table_params); - if (e) -- airoha_ppe_foe_commit_subflow_entry(ppe, e, hash); -+ airoha_ppe_foe_commit_subflow_entry(ppe, e, hash, rx_wlan); - unlock: - spin_unlock_bh(&ppe_lock); - } -@@ -1301,9 +1302,10 @@ int airoha_ppe_setup_tc_block_cb(struct - return err; - } - --void airoha_ppe_check_skb(struct airoha_ppe *ppe, struct sk_buff *skb, -- u16 hash) -+void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, -+ u16 hash, bool rx_wlan) - { -+ struct airoha_ppe *ppe = dev->priv; - u16 now, diff; - - if (hash > PPE_HASH_MASK) -@@ -1315,7 +1317,7 @@ void airoha_ppe_check_skb(struct airoha_ - return; - - ppe->foe_check_time[hash] = now; -- airoha_ppe_foe_insert_entry(ppe, skb, hash); -+ airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan); - } - - void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port) -@@ -1404,6 +1406,7 @@ int airoha_ppe_init(struct airoha_eth *e - return -ENOMEM; - - ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb; -+ ppe->dev.ops.check_skb = airoha_ppe_check_skb; - ppe->dev.priv = ppe; - - foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); ---- a/include/linux/soc/airoha/airoha_offload.h -+++ b/include/linux/soc/airoha/airoha_offload.h -@@ -9,10 +9,17 @@ - #include - #include - -+enum { -+ PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, -+}; -+ - struct airoha_ppe_dev { - struct { - int (*setup_tc_block_cb)(struct airoha_ppe_dev *dev, - void *type_data); -+ void (*check_skb)(struct airoha_ppe_dev *dev, -+ struct sk_buff *skb, u16 hash, -+ bool rx_wlan); - } ops; - - void *priv; -@@ -27,6 +34,13 @@ static inline int airoha_ppe_dev_setup_t - { - return dev->ops.setup_tc_block_cb(dev, type_data); - } -+ -+static inline void airoha_ppe_dev_check_skb(struct airoha_ppe_dev *dev, -+ struct sk_buff *skb, -+ u16 hash, bool rx_wlan) -+{ -+ dev->ops.check_skb(dev, skb, hash, rx_wlan); -+} - #else - static inline struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev) - { -@@ -42,6 +56,12 @@ static inline int airoha_ppe_setup_tc_bl - { - return -EOPNOTSUPP; - } -+ -+static inline void airoha_ppe_dev_check_skb(struct airoha_ppe_dev *dev, -+ struct sk_buff *skb, u16 hash, -+ bool rx_wlan) -+{ -+} - #endif - - #define NPU_NUM_CORES 8 diff --git a/target/linux/airoha/patches-6.12/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch b/target/linux/airoha/patches-6.12/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch deleted file mode 100644 index 62390f8a6ca..00000000000 --- a/target/linux/airoha/patches-6.12/087-v6.17-pinctrl-airoha-Fix-return-value-in-pinconf-callbacks.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 563fcd6475931c5c8c652a4dd548256314cc87ed Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 22 Aug 2025 14:14:18 +0200 -Subject: [PATCH] pinctrl: airoha: Fix return value in pinconf callbacks - -Pinctrl stack requires ENOTSUPP error code if the parameter is not -supported by the pinctrl driver. Fix the returned error code in pinconf -callbacks if the operation is not supported. - -Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/20250822-airoha-pinconf-err-val-fix-v1-1-87b4f264ced2@kernel.org -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -2697,7 +2697,7 @@ static int airoha_pinconf_get(struct pin - arg = 1; - break; - default: -- return -EOPNOTSUPP; -+ return -ENOTSUPP; - } - - *config = pinconf_to_config_packed(param, arg); -@@ -2791,7 +2791,7 @@ static int airoha_pinconf_set(struct pin - break; - } - default: -- return -EOPNOTSUPP; -+ return -ENOTSUPP; - } - } - -@@ -2808,10 +2808,10 @@ static int airoha_pinconf_group_get(stru - if (airoha_pinconf_get(pctrl_dev, - airoha_pinctrl_groups[group].pins[i], - config)) -- return -EOPNOTSUPP; -+ return -ENOTSUPP; - - if (i && cur_config != *config) -- return -EOPNOTSUPP; -+ return -ENOTSUPP; - - cur_config = *config; - } diff --git a/target/linux/airoha/patches-6.12/088-v6.18-pinctrl-airoha-replace-struct-function_desc-with-str.patch b/target/linux/airoha/patches-6.12/088-v6.18-pinctrl-airoha-replace-struct-function_desc-with-str.patch deleted file mode 100644 index 6acc9106090..00000000000 --- a/target/linux/airoha/patches-6.12/088-v6.18-pinctrl-airoha-replace-struct-function_desc-with-str.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 17d4f2a9e6cb224012d85fed52e9794a84fa501d Mon Sep 17 00:00:00 2001 -From: Bartosz Golaszewski -Date: Tue, 2 Sep 2025 13:59:13 +0200 -Subject: [PATCH 1/1] pinctrl: airoha: replace struct function_desc with struct - pinfunction - -struct function_desc is a wrapper around struct pinfunction with an -additional void *data pointer. This driver doesn't use the data pointer. -We're also working towards reducing the usage of struct function_desc in -pinctrl drivers - they should only be created by pinmux core and -accessed by drivers using pinmux_generic_get_function(). Replace the -struct function_desc objects in this driver with smaller struct -pinfunction instances. - -Tested-by: Neil Armstrong -Signed-off-by: Bartosz Golaszewski -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 15 +++++---------- - 1 file changed, 5 insertions(+), 10 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -35,13 +35,8 @@ - - #define PINCTRL_FUNC_DESC(id) \ - { \ -- .desc = { \ -- .func = { \ -- .name = #id, \ -- .groups = id##_groups, \ -- .ngroups = ARRAY_SIZE(id##_groups), \ -- } \ -- }, \ -+ .desc = PINCTRL_PINFUNCTION(#id, id##_groups, \ -+ ARRAY_SIZE(id##_groups)), \ - .groups = id##_func_group, \ - .group_size = ARRAY_SIZE(id##_func_group), \ - } -@@ -334,7 +329,7 @@ struct airoha_pinctrl_func_group { - }; - - struct airoha_pinctrl_func { -- const struct function_desc desc; -+ const struct pinfunction desc; - const struct airoha_pinctrl_func_group *groups; - u8 group_size; - }; -@@ -2911,13 +2906,13 @@ static int airoha_pinctrl_probe(struct p - - func = &airoha_pinctrl_funcs[i]; - err = pinmux_generic_add_function(pinctrl->ctrl, -- func->desc.func.name, -- func->desc.func.groups, -- func->desc.func.ngroups, -+ func->desc.name, -+ func->desc.groups, -+ func->desc.ngroups, - (void *)func); - if (err < 0) { - dev_err(dev, "Failed to register function %s\n", -- func->desc.func.name); -+ func->desc.name); - return err; - } - } diff --git a/target/linux/airoha/patches-6.12/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch b/target/linux/airoha/patches-6.12/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch deleted file mode 100644 index 4f322ec9341..00000000000 --- a/target/linux/airoha/patches-6.12/089-v6.14-net-airoha-Fix-channel-configuration-for-ETS-Qdisc.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7d0da8f862340c5f42f0062b8560b8d0971a6ac4 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 7 Jan 2025 23:26:28 +0100 -Subject: [PATCH] net: airoha: Fix channel configuration for ETS Qdisc - -Limit ETS QoS channel to AIROHA_NUM_QOS_CHANNELS in -airoha_tc_setup_qdisc_ets() in order to align the configured channel to -the value set in airoha_dev_select_queue(). - -Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Michal Swiatkowski -Link: https://patch.msgid.link/20250107-airoha-ets-fix-chan-v1-1-97f66ed3a068@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2204,11 +2204,14 @@ static int airoha_qdma_get_tx_ets_stats( - static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, - struct tc_ets_qopt_offload *opt) - { -- int channel = TC_H_MAJ(opt->handle) >> 16; -+ int channel; - - if (opt->parent == TC_H_ROOT) - return -EINVAL; - -+ channel = TC_H_MAJ(opt->handle) >> 16; -+ channel = channel % AIROHA_NUM_QOS_CHANNELS; -+ - switch (opt->command) { - case TC_ETS_REPLACE: - return airoha_qdma_set_tx_ets_sched(port, channel, opt); diff --git a/target/linux/airoha/patches-6.12/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch b/target/linux/airoha/patches-6.12/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch deleted file mode 100644 index 37b0ed5c78a..00000000000 --- a/target/linux/airoha/patches-6.12/090-v6.17-net-mdio-Add-MDIO-bus-controller-for-Airoha-AN7583.patch +++ /dev/null @@ -1,342 +0,0 @@ -From 67e3ba978361cb262f8f8981ab88ccb97f1e2bda Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 17 Jun 2025 11:16:53 +0200 -Subject: [PATCH] net: mdio: Add MDIO bus controller for Airoha AN7583 - -Airoha AN7583 SoC have 2 dedicated MDIO bus controller in the SCU -register map. To driver register an MDIO controller based on the DT -reg property and access the register by accessing the parent syscon. - -The MDIO bus logic is similar to the MT7530 internal MDIO bus but -deviates of some setting and some HW bug. - -On Airoha AN7583 the MDIO clock is set to 25MHz by default and needs to -be correctly setup to 2.5MHz to correctly work (by setting the divisor -to 10x). - -There seems to be Hardware bug where AN7583_MII_RWDATA -is not wiped in the context of unconnected PHY and the -previous read value is returned. - -Example: (only one PHY on the BUS at 0x1f) - - read at 0x1f report at 0x2 0x7500 - - read at 0x0 report 0x7500 on every address - -To workaround this, we reset the Mdio BUS at every read -to have consistent values on read operation. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/mdio/Kconfig | 7 + - drivers/net/mdio/Makefile | 1 + - drivers/net/mdio/mdio-airoha.c | 276 +++++++++++++++++++++++++++++++++ - 3 files changed, 284 insertions(+) - create mode 100644 drivers/net/mdio/mdio-airoha.c - ---- a/drivers/net/mdio/Kconfig -+++ b/drivers/net/mdio/Kconfig -@@ -46,6 +46,13 @@ if MDIO_BUS - config MDIO_DEVRES - tristate - -+config MDIO_AIROHA -+ tristate "Airoha AN7583 MDIO bus controller" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ help -+ This module provides a driver for the MDIO busses found in the -+ Airoha AN7583 SoC's. -+ - config MDIO_SUN4I - tristate "Allwinner sun4i MDIO interface support" - depends on ARCH_SUNXI || COMPILE_TEST ---- a/drivers/net/mdio/Makefile -+++ b/drivers/net/mdio/Makefile -@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO) += acpi_mdio.o - obj-$(CONFIG_FWNODE_MDIO) += fwnode_mdio.o - obj-$(CONFIG_OF_MDIO) += of_mdio.o - -+obj-$(CONFIG_MDIO_AIROHA) += mdio-airoha.o - obj-$(CONFIG_MDIO_ASPEED) += mdio-aspeed.o - obj-$(CONFIG_MDIO_BCM_IPROC) += mdio-bcm-iproc.o - obj-$(CONFIG_MDIO_BCM_UNIMAC) += mdio-bcm-unimac.o ---- /dev/null -+++ b/drivers/net/mdio/mdio-airoha.c -@@ -0,0 +1,276 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Airoha AN7583 MDIO interface driver -+ * -+ * Copyright (C) 2025 Christian Marangi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* MII address register definitions */ -+#define AN7583_MII_BUSY BIT(31) -+#define AN7583_MII_RDY BIT(30) /* RO signal BUS is ready */ -+#define AN7583_MII_CL22_REG_ADDR GENMASK(29, 25) -+#define AN7583_MII_CL45_DEV_ADDR AN7583_MII_CL22_REG_ADDR -+#define AN7583_MII_PHY_ADDR GENMASK(24, 20) -+#define AN7583_MII_CMD GENMASK(19, 18) -+#define AN7583_MII_CMD_CL22_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1) -+#define AN7583_MII_CMD_CL22_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x2) -+#define AN7583_MII_CMD_CL45_ADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x0) -+#define AN7583_MII_CMD_CL45_WRITE FIELD_PREP_CONST(AN7583_MII_CMD, 0x1) -+#define AN7583_MII_CMD_CL45_POSTREAD_INCADDR FIELD_PREP_CONST(AN7583_MII_CMD, 0x2) -+#define AN7583_MII_CMD_CL45_READ FIELD_PREP_CONST(AN7583_MII_CMD, 0x3) -+#define AN7583_MII_ST GENMASK(17, 16) -+#define AN7583_MII_ST_CL45 FIELD_PREP_CONST(AN7583_MII_ST, 0x0) -+#define AN7583_MII_ST_CL22 FIELD_PREP_CONST(AN7583_MII_ST, 0x1) -+#define AN7583_MII_RWDATA GENMASK(15, 0) -+#define AN7583_MII_CL45_REG_ADDR AN7583_MII_RWDATA -+ -+#define AN7583_MII_MDIO_DELAY_USEC 100 -+#define AN7583_MII_MDIO_RETRY_MSEC 100 -+ -+struct airoha_mdio_data { -+ u32 base_addr; -+ struct regmap *regmap; -+ struct clk *clk; -+ struct reset_control *reset; -+}; -+ -+static int airoha_mdio_wait_busy(struct airoha_mdio_data *priv) -+{ -+ u32 busy; -+ -+ return regmap_read_poll_timeout(priv->regmap, priv->base_addr, busy, -+ !(busy & AN7583_MII_BUSY), -+ AN7583_MII_MDIO_DELAY_USEC, -+ AN7583_MII_MDIO_RETRY_MSEC * USEC_PER_MSEC); -+} -+ -+static void airoha_mdio_reset(struct airoha_mdio_data *priv) -+{ -+ /* There seems to be Hardware bug where AN7583_MII_RWDATA -+ * is not wiped in the context of unconnected PHY and the -+ * previous read value is returned. -+ * -+ * Example: (only one PHY on the BUS at 0x1f) -+ * - read at 0x1f report at 0x2 0x7500 -+ * - read at 0x0 report 0x7500 on every address -+ * -+ * To workaround this, we reset the Mdio BUS at every read -+ * to have consistent values on read operation. -+ */ -+ reset_control_assert(priv->reset); -+ reset_control_deassert(priv->reset); -+} -+ -+static int airoha_mdio_read(struct mii_bus *bus, int addr, int regnum) -+{ -+ struct airoha_mdio_data *priv = bus->priv; -+ u32 val; -+ int ret; -+ -+ airoha_mdio_reset(priv); -+ -+ val = AN7583_MII_BUSY | AN7583_MII_ST_CL22 | -+ AN7583_MII_CMD_CL22_READ; -+ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); -+ val |= FIELD_PREP(AN7583_MII_CL22_REG_ADDR, regnum); -+ -+ ret = regmap_write(priv->regmap, priv->base_addr, val); -+ if (ret) -+ return ret; -+ -+ ret = airoha_mdio_wait_busy(priv); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(priv->regmap, priv->base_addr, &val); -+ if (ret) -+ return ret; -+ -+ return FIELD_GET(AN7583_MII_RWDATA, val); -+} -+ -+static int airoha_mdio_write(struct mii_bus *bus, int addr, int regnum, -+ u16 value) -+{ -+ struct airoha_mdio_data *priv = bus->priv; -+ u32 val; -+ int ret; -+ -+ val = AN7583_MII_BUSY | AN7583_MII_ST_CL22 | -+ AN7583_MII_CMD_CL22_WRITE; -+ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); -+ val |= FIELD_PREP(AN7583_MII_CL22_REG_ADDR, regnum); -+ val |= FIELD_PREP(AN7583_MII_RWDATA, value); -+ -+ ret = regmap_write(priv->regmap, priv->base_addr, val); -+ if (ret) -+ return ret; -+ -+ ret = airoha_mdio_wait_busy(priv); -+ -+ return ret; -+} -+ -+static int airoha_mdio_cl45_read(struct mii_bus *bus, int addr, int devnum, -+ int regnum) -+{ -+ struct airoha_mdio_data *priv = bus->priv; -+ u32 val; -+ int ret; -+ -+ airoha_mdio_reset(priv); -+ -+ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | -+ AN7583_MII_CMD_CL45_ADDR; -+ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); -+ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); -+ val |= FIELD_PREP(AN7583_MII_CL45_REG_ADDR, regnum); -+ -+ ret = regmap_write(priv->regmap, priv->base_addr, val); -+ if (ret) -+ return ret; -+ -+ ret = airoha_mdio_wait_busy(priv); -+ if (ret) -+ return ret; -+ -+ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | -+ AN7583_MII_CMD_CL45_READ; -+ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); -+ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); -+ -+ ret = regmap_write(priv->regmap, priv->base_addr, val); -+ if (ret) -+ return ret; -+ -+ ret = airoha_mdio_wait_busy(priv); -+ if (ret) -+ return ret; -+ -+ ret = regmap_read(priv->regmap, priv->base_addr, &val); -+ if (ret) -+ return ret; -+ -+ return FIELD_GET(AN7583_MII_RWDATA, val); -+} -+ -+static int airoha_mdio_cl45_write(struct mii_bus *bus, int addr, int devnum, -+ int regnum, u16 value) -+{ -+ struct airoha_mdio_data *priv = bus->priv; -+ u32 val; -+ int ret; -+ -+ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | -+ AN7583_MII_CMD_CL45_ADDR; -+ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); -+ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); -+ val |= FIELD_PREP(AN7583_MII_CL45_REG_ADDR, regnum); -+ -+ ret = regmap_write(priv->regmap, priv->base_addr, val); -+ if (ret) -+ return ret; -+ -+ ret = airoha_mdio_wait_busy(priv); -+ if (ret) -+ return ret; -+ -+ val = AN7583_MII_BUSY | AN7583_MII_ST_CL45 | -+ AN7583_MII_CMD_CL45_WRITE; -+ val |= FIELD_PREP(AN7583_MII_PHY_ADDR, addr); -+ val |= FIELD_PREP(AN7583_MII_CL45_DEV_ADDR, devnum); -+ val |= FIELD_PREP(AN7583_MII_RWDATA, value); -+ -+ ret = regmap_write(priv->regmap, priv->base_addr, val); -+ if (ret) -+ return ret; -+ -+ ret = airoha_mdio_wait_busy(priv); -+ -+ return ret; -+} -+ -+static int airoha_mdio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct airoha_mdio_data *priv; -+ struct mii_bus *bus; -+ u32 addr, freq; -+ int ret; -+ -+ ret = of_property_read_u32(dev->of_node, "reg", &addr); -+ if (ret) -+ return ret; -+ -+ bus = devm_mdiobus_alloc_size(dev, sizeof(*priv)); -+ if (!bus) -+ return -ENOMEM; -+ -+ priv = bus->priv; -+ priv->base_addr = addr; -+ priv->regmap = device_node_to_regmap(dev->parent->of_node); -+ -+ priv->clk = devm_clk_get_enabled(dev, NULL); -+ if (IS_ERR(priv->clk)) -+ return PTR_ERR(priv->clk); -+ -+ priv->reset = devm_reset_control_get_exclusive(dev, NULL); -+ if (IS_ERR(priv->reset)) -+ return PTR_ERR(priv->reset); -+ -+ reset_control_deassert(priv->reset); -+ -+ bus->name = "airoha_mdio_bus"; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev)); -+ bus->parent = dev; -+ bus->read = airoha_mdio_read; -+ bus->write = airoha_mdio_write; -+ bus->read_c45 = airoha_mdio_cl45_read; -+ bus->write_c45 = airoha_mdio_cl45_write; -+ -+ /* Check if a custom frequency is defined in DT or default to 2.5 MHz */ -+ if (of_property_read_u32(dev->of_node, "clock-frequency", &freq)) -+ freq = 2500000; -+ -+ ret = clk_set_rate(priv->clk, freq); -+ if (ret) -+ return ret; -+ -+ ret = devm_of_mdiobus_register(dev, bus, dev->of_node); -+ if (ret) { -+ reset_control_assert(priv->reset); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id airoha_mdio_dt_ids[] = { -+ { .compatible = "airoha,an7583-mdio" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, airoha_mdio_dt_ids); -+ -+static struct platform_driver airoha_mdio_driver = { -+ .probe = airoha_mdio_probe, -+ .driver = { -+ .name = "airoha-mdio", -+ .of_match_table = airoha_mdio_dt_ids, -+ }, -+}; -+ -+module_platform_driver(airoha_mdio_driver); -+ -+MODULE_DESCRIPTION("Airoha AN7583 MDIO interface driver"); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch b/target/linux/airoha/patches-6.12/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch deleted file mode 100644 index cf16391b7be..00000000000 --- a/target/linux/airoha/patches-6.12/091-01-v6.18-pinctrl-airoha-fix-wrong-PHY-LED-mux-value-for-LED1-.patch +++ /dev/null @@ -1,68 +0,0 @@ -From af87d38c442c75a40c7d0a7d8c31557e2e6ccf98 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 25 May 2025 20:22:40 +0200 -Subject: [PATCH 1/2] pinctrl: airoha: fix wrong PHY LED mux value for LED1 - GPIO46 - -In all the MUX value for LED1 GPIO46 there is a Copy-Paste error where -the MUX value is set to LED0_MODE_MASK instead of LED1_MODE_MASK. - -This wasn't notice as there were no board that made use of the -secondary PHY LED but looking at the internal Documentation the actual -value should be LED1_MODE_MASK similar to the other GPIO entry. - -Fix the wrong value to apply the correct MUX configuration. - -Cc: stable@vger.kernel.org -Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") -Signed-off-by: Christian Marangi ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -1747,8 +1747,8 @@ static const struct airoha_pinctrl_func_ - .regmap[0] = { - AIROHA_FUNC_MUX, - REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -+ GPIO_LAN3_LED1_MODE_MASK, -+ GPIO_LAN3_LED1_MODE_MASK - }, - .regmap[1] = { - AIROHA_FUNC_MUX, -@@ -1811,8 +1811,8 @@ static const struct airoha_pinctrl_func_ - .regmap[0] = { - AIROHA_FUNC_MUX, - REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -+ GPIO_LAN3_LED1_MODE_MASK, -+ GPIO_LAN3_LED1_MODE_MASK - }, - .regmap[1] = { - AIROHA_FUNC_MUX, -@@ -1875,8 +1875,8 @@ static const struct airoha_pinctrl_func_ - .regmap[0] = { - AIROHA_FUNC_MUX, - REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -+ GPIO_LAN3_LED1_MODE_MASK, -+ GPIO_LAN3_LED1_MODE_MASK - }, - .regmap[1] = { - AIROHA_FUNC_MUX, -@@ -1939,8 +1939,8 @@ static const struct airoha_pinctrl_func_ - .regmap[0] = { - AIROHA_FUNC_MUX, - REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -+ GPIO_LAN3_LED1_MODE_MASK, -+ GPIO_LAN3_LED1_MODE_MASK - }, - .regmap[1] = { - AIROHA_FUNC_MUX, diff --git a/target/linux/airoha/patches-6.12/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch b/target/linux/airoha/patches-6.12/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch deleted file mode 100644 index 0f0a5ebe0f7..00000000000 --- a/target/linux/airoha/patches-6.12/091-02-v6.18-pinctrl-airoha-fix-wrong-MDIO-function-bitmaks.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 110930eb12699b92f767fc599c7ab467dd42358a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 8 Jul 2025 14:49:56 +0200 -Subject: [PATCH 2/2] pinctrl: airoha: fix wrong MDIO function bitmaks - -With further testing with an attached Aeonsemi it was discovered that -the pinctrl MDIO function applied the wrong bitmask. The error was -probably caused by the confusing documentation related to these bits. - -Inspecting what the bootloader actually configure, the SGMII_MDIO_MODE -is never actually set but instead it's set force enable to the 2 GPIO -(gpio 1-2) for MDC and MDIO pin. - -Applying this configuration permits correct functionality of any -externally attached PHY. - -Cc: stable@vger.kernel.org -Fixes: 1c8ace2d0725 ("pinctrl: airoha: Add support for EN7581 SoC") -Signed-off-by: Christian Marangi ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -103,6 +103,9 @@ - #define JTAG_UDI_EN_MASK BIT(4) - #define JTAG_DFD_EN_MASK BIT(3) - -+#define REG_FORCE_GPIO_EN 0x0228 -+#define FORCE_GPIO_EN(n) BIT(n) -+ - /* LED MAP */ - #define REG_LAN_LED0_MAPPING 0x027c - #define REG_LAN_LED1_MAPPING 0x0280 -@@ -714,16 +717,16 @@ static const struct airoha_pinctrl_func_ - .name = "mdio", - .regmap[0] = { - AIROHA_FUNC_MUX, -- REG_GPIO_PON_MODE, -- GPIO_SGMII_MDIO_MODE_MASK, -- GPIO_SGMII_MDIO_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, - REG_GPIO_2ND_I2C_MODE, - GPIO_MDC_IO_MASTER_MODE_MODE, - GPIO_MDC_IO_MASTER_MODE_MODE - }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_FORCE_GPIO_EN, -+ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2), -+ FORCE_GPIO_EN(1) | FORCE_GPIO_EN(2) -+ }, - .regmap_size = 2, - }, - }; diff --git a/target/linux/airoha/patches-6.12/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch b/target/linux/airoha/patches-6.12/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch deleted file mode 100644 index 5e52a3b429e..00000000000 --- a/target/linux/airoha/patches-6.12/092-v6.18-net-airoha-Avoid-Wflex-array-member-not-at-end-warni.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 09630ab91d840416b0178f3660afa4eebce24286 Mon Sep 17 00:00:00 2001 -From: "Gustavo A. R. Silva" -Date: Mon, 22 Sep 2025 16:08:21 +0200 -Subject: [PATCH] net: airoha: Avoid -Wflex-array-member-not-at-end warning - --Wflex-array-member-not-at-end was introduced in GCC-14, and we are -getting ready to enable it, globally. - -Move the conflicting declaration to the end of the corresponding -structure. Notice that `struct airoha_foe_entry` is a flexible -structure, this is a structure that contains a flexible-array -member. - -Fix the following warning: - -drivers/net/ethernet/airoha/airoha_eth.h:474:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] - -Signed-off-by: Gustavo A. R. Silva -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/aNFYVYLXQDqm4yxb@kspp -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.h | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -471,7 +471,6 @@ struct airoha_flow_table_entry { - }; - }; - -- struct airoha_foe_entry data; - struct hlist_node l2_subflow_node; /* PPE L2 subflow entry */ - u32 hash; - -@@ -480,6 +479,9 @@ struct airoha_flow_table_entry { - - struct rhash_head node; - unsigned long cookie; -+ -+ /* Must be last --ends in a flexible-array member. */ -+ struct airoha_foe_entry data; - }; - - struct airoha_wdma_info { diff --git a/target/linux/airoha/patches-6.12/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch b/target/linux/airoha/patches-6.12/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch deleted file mode 100644 index 31cd950437e..00000000000 --- a/target/linux/airoha/patches-6.12/093-v6.18-net-airoha-Fix-PPE_IP_PROTO_CHK-register-definitions.patch +++ /dev/null @@ -1,29 +0,0 @@ -From e156dd6b856fa462430d875b0d4cd281ecd66c23 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 18 Sep 2025 08:59:41 +0200 -Subject: [PATCH] net: airoha: Fix PPE_IP_PROTO_CHK register definitions - -Fix typo in PPE_IP_PROTO_CHK_IPV4_MASK and PPE_IP_PROTO_CHK_IPV6_MASK -register mask definitions. This is not a real problem since this -register is not actually used in the current codebase. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_regs.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -237,8 +237,8 @@ - #define PPE_FLOW_CFG_IP4_TCP_FRAG_MASK BIT(6) - - #define REG_PPE_IP_PROTO_CHK(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x208) --#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(15, 0) --#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(31, 16) -+#define PPE_IP_PROTO_CHK_IPV4_MASK GENMASK(31, 16) -+#define PPE_IP_PROTO_CHK_IPV6_MASK GENMASK(15, 0) - - #define REG_PPE_TB_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x21c) - #define PPE_SRAM_TB_NUM_ENTRY_MASK GENMASK(26, 24) diff --git a/target/linux/airoha/patches-6.12/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch b/target/linux/airoha/patches-6.12/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch deleted file mode 100644 index 021ec0c8df5..00000000000 --- a/target/linux/airoha/patches-6.12/094-v6.18-net-airoha-npu-Add-a-NPU-callback-to-initialize-flow.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 105ce7ad57e492b75ab40f2dc591db645fadbaa2 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 24 Sep 2025 23:14:53 +0200 -Subject: [PATCH] net: airoha: npu: Add a NPU callback to initialize flow stats - -Introduce a NPU callback to initialize flow stats and remove NPU stats -initialization from airoha_npu_get routine. Add num_stats_entries to -airoha_npu_ppe_stats_setup routine. -This patch makes the code more readable since NPU statistic are now -initialized on demand by the NPU consumer (at the moment NPU statistic -are configured just by the airoha_eth driver). -Moreover this patch allows the NPU consumer (PPE module) to explicitly -enable/disable NPU flow stats. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20250924-airoha-npu-init-stats-callback-v1-1-88bdf3c941b2@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 24 ++++++----------------- - drivers/net/ethernet/airoha/airoha_ppe.c | 19 ++++++++++++------ - include/linux/soc/airoha/airoha_offload.h | 7 ++++--- - 3 files changed, 23 insertions(+), 27 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -379,15 +379,13 @@ out: - return err; - } - --static int airoha_npu_stats_setup(struct airoha_npu *npu, -- dma_addr_t foe_stats_addr) -+static int airoha_npu_ppe_stats_setup(struct airoha_npu *npu, -+ dma_addr_t foe_stats_addr, -+ u32 num_stats_entries) - { -- int err, size = PPE_STATS_NUM_ENTRIES * sizeof(*npu->stats); -+ int err, size = num_stats_entries * sizeof(*npu->stats); - struct ppe_mbox_data *ppe_data; - -- if (!size) /* flow stats are disabled */ -- return 0; -- - ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); - if (!ppe_data) - return -ENOMEM; -@@ -542,7 +540,7 @@ static void airoha_npu_wlan_irq_disable( - regmap_clear_bits(npu->regmap, REG_IRQ_RXDONE(q), NPU_IRQ_RX_MASK(q)); - } - --struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr) -+struct airoha_npu *airoha_npu_get(struct device *dev) - { - struct platform_device *pdev; - struct device_node *np; -@@ -580,17 +578,6 @@ struct airoha_npu *airoha_npu_get(struct - goto error_module_put; - } - -- if (stats_addr) { -- int err; -- -- err = airoha_npu_stats_setup(npu, *stats_addr); -- if (err) { -- dev_err(dev, "failed to allocate npu stats buffer\n"); -- npu = ERR_PTR(err); -- goto error_module_put; -- } -- } -- - return npu; - - error_module_put: -@@ -643,6 +630,7 @@ static int airoha_npu_probe(struct platf - npu->dev = dev; - npu->ops.ppe_init = airoha_npu_ppe_init; - npu->ops.ppe_deinit = airoha_npu_ppe_deinit; -+ npu->ops.ppe_init_stats = airoha_npu_ppe_stats_setup; - npu->ops.ppe_flush_sram_entries = airoha_npu_ppe_flush_sram_entries; - npu->ops.ppe_foe_commit_entry = airoha_npu_foe_commit_entry; - npu->ops.wlan_init_reserved_memory = airoha_npu_wlan_init_memory; ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -1243,12 +1243,11 @@ static int airoha_ppe_flush_sram_entries - - static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) - { -- struct airoha_npu *npu = airoha_npu_get(eth->dev, -- ð->ppe->foe_stats_dma); -+ struct airoha_npu *npu = airoha_npu_get(eth->dev); - - if (IS_ERR(npu)) { - request_module("airoha-npu"); -- npu = airoha_npu_get(eth->dev, ð->ppe->foe_stats_dma); -+ npu = airoha_npu_get(eth->dev); - } - - return npu; -@@ -1257,6 +1256,7 @@ static struct airoha_npu *airoha_ppe_npu - static int airoha_ppe_offload_setup(struct airoha_eth *eth) - { - struct airoha_npu *npu = airoha_ppe_npu_get(eth); -+ struct airoha_ppe *ppe = eth->ppe; - int err; - - if (IS_ERR(npu)) -@@ -1266,12 +1266,19 @@ static int airoha_ppe_offload_setup(stru - if (err) - goto error_npu_put; - -- airoha_ppe_hw_init(eth->ppe); -- err = airoha_ppe_flush_sram_entries(eth->ppe, npu); -+ if (PPE_STATS_NUM_ENTRIES) { -+ err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma, -+ PPE_STATS_NUM_ENTRIES); -+ if (err) -+ goto error_npu_put; -+ } -+ -+ airoha_ppe_hw_init(ppe); -+ err = airoha_ppe_flush_sram_entries(ppe, npu); - if (err) - goto error_npu_put; - -- airoha_ppe_foe_flow_stats_reset(eth->ppe, npu); -+ airoha_ppe_foe_flow_stats_reset(ppe, npu); - - rcu_assign_pointer(eth->npu, npu); - synchronize_rcu(); ---- a/include/linux/soc/airoha/airoha_offload.h -+++ b/include/linux/soc/airoha/airoha_offload.h -@@ -181,6 +181,8 @@ struct airoha_npu { - struct { - int (*ppe_init)(struct airoha_npu *npu); - int (*ppe_deinit)(struct airoha_npu *npu); -+ int (*ppe_init_stats)(struct airoha_npu *npu, -+ dma_addr_t addr, u32 num_stats_entries); - int (*ppe_flush_sram_entries)(struct airoha_npu *npu, - dma_addr_t foe_addr, - int sram_num_entries); -@@ -206,7 +208,7 @@ struct airoha_npu { - }; - - #if (IS_BUILTIN(CONFIG_NET_AIROHA_NPU) || IS_MODULE(CONFIG_NET_AIROHA_NPU)) --struct airoha_npu *airoha_npu_get(struct device *dev, dma_addr_t *stats_addr); -+struct airoha_npu *airoha_npu_get(struct device *dev); - void airoha_npu_put(struct airoha_npu *npu); - - static inline int airoha_npu_wlan_init_reserved_memory(struct airoha_npu *npu) -@@ -256,8 +258,7 @@ static inline void airoha_npu_wlan_disab - npu->ops.wlan_disable_irq(npu, q); - } - #else --static inline struct airoha_npu *airoha_npu_get(struct device *dev, -- dma_addr_t *foe_stats_addr) -+static inline struct airoha_npu *airoha_npu_get(struct device *dev) - { - return NULL; - } diff --git a/target/linux/airoha/patches-6.12/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch b/target/linux/airoha/patches-6.12/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch deleted file mode 100644 index 85d82e850bb..00000000000 --- a/target/linux/airoha/patches-6.12/095-v6.19-net-airoha-Fix-loopback-mode-configuration-for-GDM2-.patch +++ /dev/null @@ -1,43 +0,0 @@ -From fea8cdf6738a8b25fccbb7b109b440795a0892cb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Oct 2025 11:27:43 +0200 -Subject: [PATCH] net: airoha: Fix loopback mode configuration for GDM2 port - -Add missing configuration for loopback mode in airhoha_set_gdm2_loopback -routine. - -Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Jacob Keller -Link: https://patch.msgid.link/20251008-airoha-loopback-mode-fix-v2-1-045694fe7f60@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 4 +++- - drivers/net/ethernet/airoha/airoha_regs.h | 3 +++ - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1736,7 +1736,9 @@ static void airhoha_set_gdm2_loopback(st - airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); - airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), - LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, -- FIELD_PREP(LPBK_CHAN_MASK, chan) | LPBK_EN_MASK); -+ FIELD_PREP(LPBK_CHAN_MASK, chan) | -+ LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK | -+ LBK_CHAN_MODE_MASK | LPBK_EN_MASK); - airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), - GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, - FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -151,6 +151,9 @@ - #define LPBK_LEN_MASK GENMASK(23, 10) - #define LPBK_CHAN_MASK GENMASK(8, 4) - #define LPBK_MODE_MASK GENMASK(3, 1) -+#define LBK_GAP_MODE_MASK BIT(3) -+#define LBK_LEN_MODE_MASK BIT(2) -+#define LBK_CHAN_MODE_MASK BIT(1) - #define LPBK_EN_MASK BIT(0) - - #define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) diff --git a/target/linux/airoha/patches-6.12/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch b/target/linux/airoha/patches-6.12/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch deleted file mode 100644 index c6b7541732c..00000000000 --- a/target/linux/airoha/patches-6.12/096-v6.19-net-airoha-Add-missing-stats-to-ethtool_eth_mac_stat.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 331f8a8bea22aecf99437f3561453a85f40026de Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 13 Oct 2025 16:29:41 +0200 -Subject: [PATCH] net: airoha: Add missing stats to ethtool_eth_mac_stats - -Add the following stats to ethtool ethtool_eth_mac_stats stats: -- FramesTransmittedOK -- OctetsTransmittedOK -- FramesReceivedOK -- OctetsReceivedOK - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20251013-airoha-ethtool-improvements-v1-1-fdd1c6fc9be1@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2048,8 +2048,12 @@ static void airoha_ethtool_get_mac_stats - airoha_update_hw_stats(port); - do { - start = u64_stats_fetch_begin(&port->stats.syncp); -+ stats->FramesTransmittedOK = port->stats.tx_ok_pkts; -+ stats->OctetsTransmittedOK = port->stats.tx_ok_bytes; - stats->MulticastFramesXmittedOK = port->stats.tx_multicast; - stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; -+ stats->FramesReceivedOK = port->stats.rx_ok_pkts; -+ stats->OctetsReceivedOK = port->stats.rx_ok_bytes; - stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } diff --git a/target/linux/airoha/patches-6.12/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch b/target/linux/airoha/patches-6.12/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch deleted file mode 100644 index 4754e2dfb43..00000000000 --- a/target/linux/airoha/patches-6.12/097-v6.19-net-airoha-Add-get_link-ethtool-callback.patch +++ /dev/null @@ -1,25 +0,0 @@ -From fc4fed9054ef5b5269d4395dd9db36fe98fce9e3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 13 Oct 2025 16:29:42 +0200 -Subject: [PATCH] net: airoha: Add get_link ethtool callback - -Set get_link ethtool callback to ethtool_op_get_link routine. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20251013-airoha-ethtool-improvements-v1-2-fdd1c6fc9be1@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2796,6 +2796,7 @@ static const struct ethtool_ops airoha_e - .get_drvinfo = airoha_ethtool_get_drvinfo, - .get_eth_mac_stats = airoha_ethtool_get_mac_stats, - .get_rmon_stats = airoha_ethtool_get_rmon_stats, -+ .get_link = ethtool_op_get_link, - }; - - static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) diff --git a/target/linux/airoha/patches-6.12/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch b/target/linux/airoha/patches-6.12/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch deleted file mode 100644 index 4fcae92d7a3..00000000000 --- a/target/linux/airoha/patches-6.12/098-v6.19-net-airoha-Take-into-account-out-of-order-tx-complet.patch +++ /dev/null @@ -1,54 +0,0 @@ -From bd5afca115f181c85f992d42a57cd497bc823ccb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Oct 2025 11:19:44 +0200 -Subject: [PATCH] net: airoha: Take into account out-of-order tx completions in - airoha_dev_xmit() - -Completion napi can free out-of-order tx descriptors if hw QoS is -enabled and packets with different priority are queued to same DMA ring. -Take into account possible out-of-order reports checking if the tx queue -is full using circular buffer head/tail pointer instead of the number of -queued packets. - -Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Suggested-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20251012-airoha-tx-busy-queue-v2-1-a600b08bab2d@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1899,6 +1899,20 @@ static u32 airoha_get_dsa_tag(struct sk_ - #endif - } - -+static bool airoha_dev_tx_queue_busy(struct airoha_queue *q, u32 nr_frags) -+{ -+ u32 tail = q->tail <= q->head ? q->tail + q->ndesc : q->tail; -+ u32 index = q->head + nr_frags; -+ -+ /* completion napi can free out-of-order tx descriptors if hw QoS is -+ * enabled and packets with different priorities are queued to the same -+ * DMA ring. Take into account possible out-of-order reports checking -+ * if the tx queue is full using circular buffer head/tail pointers -+ * instead of the number of queued packets. -+ */ -+ return index >= tail; -+} -+ - static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, - struct net_device *dev) - { -@@ -1952,7 +1966,7 @@ static netdev_tx_t airoha_dev_xmit(struc - txq = netdev_get_tx_queue(dev, qid); - nr_frags = 1 + skb_shinfo(skb)->nr_frags; - -- if (q->queued + nr_frags > q->ndesc) { -+ if (airoha_dev_tx_queue_busy(q, nr_frags)) { - /* not enough space in the queue */ - netif_tx_stop_queue(txq); - spin_unlock_bh(&q->lock); diff --git a/target/linux/airoha/patches-6.12/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch b/target/linux/airoha/patches-6.12/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch deleted file mode 100644 index 3d4b0cfab06..00000000000 --- a/target/linux/airoha/patches-6.12/099-01-v6.19-net-airoha-ppe-Dynamically-allocate-foe_check_time-a.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 6d5b601d52a27aafff555b480e538507901c672c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:11 +0200 -Subject: [PATCH 01/12] net: airoha: ppe: Dynamically allocate foe_check_time - array in airoha_ppe struct - -This is a preliminary patch to properly enable PPE support for AN7583 -SoC. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-2-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 5 +++++ - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -554,7 +554,7 @@ struct airoha_ppe { - struct rhashtable l2_flows; - - struct hlist_head *foe_flow; -- u16 foe_check_time[PPE_NUM_ENTRIES]; -+ u16 *foe_check_time; - - struct airoha_foe_stats *foe_stats; - dma_addr_t foe_stats_dma; ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -1440,6 +1440,11 @@ int airoha_ppe_init(struct airoha_eth *e - return -ENOMEM; - } - -+ ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES, -+ GFP_KERNEL); -+ if (!ppe->foe_check_time) -+ return -ENOMEM; -+ - err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); - if (err) - return err; diff --git a/target/linux/airoha/patches-6.12/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch b/target/linux/airoha/patches-6.12/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch deleted file mode 100644 index 6733331f1f3..00000000000 --- a/target/linux/airoha/patches-6.12/099-02-v6.19-net-airoha-Add-airoha_ppe_get_num_stats_entries-and-.patch +++ /dev/null @@ -1,239 +0,0 @@ -From 15f357cd4581ce6e02e5e97719320600783140ec Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:12 +0200 -Subject: [PATCH 02/12] net: airoha: Add airoha_ppe_get_num_stats_entries() and - airoha_ppe_get_num_total_stats_entries() - -Introduce airoha_ppe_get_num_stats_entries and -airoha_ppe_get_num_total_stats_entries routines in order to make the -code more readable controlling if CONFIG_NET_AIROHA_FLOW_STATS is -enabled or disabled. -Modify airoha_ppe_foe_get_flow_stats_index routine signature relying on -airoha_ppe_get_num_total_stats_entries(). - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-3-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.h | 10 +-- - drivers/net/ethernet/airoha/airoha_ppe.c | 101 ++++++++++++++++++----- - 2 files changed, 81 insertions(+), 30 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -50,15 +50,9 @@ - - #define PPE_NUM 2 - #define PPE1_SRAM_NUM_ENTRIES (8 * 1024) --#define PPE_SRAM_NUM_ENTRIES (2 * PPE1_SRAM_NUM_ENTRIES) --#ifdef CONFIG_NET_AIROHA_FLOW_STATS -+#define PPE_SRAM_NUM_ENTRIES (PPE_NUM * PPE1_SRAM_NUM_ENTRIES) - #define PPE1_STATS_NUM_ENTRIES (4 * 1024) --#else --#define PPE1_STATS_NUM_ENTRIES 0 --#endif /* CONFIG_NET_AIROHA_FLOW_STATS */ --#define PPE_STATS_NUM_ENTRIES (2 * PPE1_STATS_NUM_ENTRIES) --#define PPE1_SRAM_NUM_DATA_ENTRIES (PPE1_SRAM_NUM_ENTRIES - PPE1_STATS_NUM_ENTRIES) --#define PPE_SRAM_NUM_DATA_ENTRIES (2 * PPE1_SRAM_NUM_DATA_ENTRIES) -+#define PPE_STATS_NUM_ENTRIES (PPE_NUM * PPE1_STATS_NUM_ENTRIES) - #define PPE_DRAM_NUM_ENTRIES (16 * 1024) - #define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) - #define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -32,6 +32,24 @@ static const struct rhashtable_params ai - .automatic_shrinking = true, - }; - -+static int airoha_ppe_get_num_stats_entries(struct airoha_ppe *ppe) -+{ -+ if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) -+ return -EOPNOTSUPP; -+ -+ return PPE1_STATS_NUM_ENTRIES; -+} -+ -+static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe) -+{ -+ int num_stats = airoha_ppe_get_num_stats_entries(ppe); -+ -+ if (num_stats > 0) -+ num_stats = num_stats * PPE_NUM; -+ -+ return num_stats; -+} -+ - static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) - { - return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; -@@ -48,7 +66,7 @@ static void airoha_ppe_hw_init(struct ai - { - u32 sram_tb_size, sram_num_entries, dram_num_entries; - struct airoha_eth *eth = ppe->eth; -- int i; -+ int i, sram_num_stats_entries; - - sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); - dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); -@@ -103,8 +121,13 @@ static void airoha_ppe_hw_init(struct ai - } - - if (airoha_ppe2_is_enabled(eth)) { -- sram_num_entries = -- PPE_RAM_NUM_ENTRIES_SHIFT(PPE1_SRAM_NUM_DATA_ENTRIES); -+ sram_num_entries = PPE1_SRAM_NUM_ENTRIES; -+ sram_num_stats_entries = -+ airoha_ppe_get_num_stats_entries(ppe); -+ if (sram_num_stats_entries > 0) -+ sram_num_entries -= sram_num_stats_entries; -+ sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); -+ - airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), - PPE_SRAM_TB_NUM_ENTRY_MASK | - PPE_DRAM_TB_NUM_ENTRY_MASK, -@@ -120,8 +143,13 @@ static void airoha_ppe_hw_init(struct ai - FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, - dram_num_entries)); - } else { -- sram_num_entries = -- PPE_RAM_NUM_ENTRIES_SHIFT(PPE_SRAM_NUM_DATA_ENTRIES); -+ sram_num_entries = PPE_SRAM_NUM_ENTRIES; -+ sram_num_stats_entries = -+ airoha_ppe_get_total_num_stats_entries(ppe); -+ if (sram_num_stats_entries > 0) -+ sram_num_entries -= sram_num_stats_entries; -+ sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); -+ - airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), - PPE_SRAM_TB_NUM_ENTRY_MASK | - PPE_DRAM_TB_NUM_ENTRY_MASK, -@@ -480,13 +508,21 @@ static u32 airoha_ppe_foe_get_entry_hash - return hash; - } - --static u32 airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, u32 hash) -+static int airoha_ppe_foe_get_flow_stats_index(struct airoha_ppe *ppe, -+ u32 hash, u32 *index) - { -- if (!airoha_ppe2_is_enabled(ppe->eth)) -- return hash; -+ int ppe_num_stats_entries; -+ -+ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); -+ if (ppe_num_stats_entries < 0) -+ return ppe_num_stats_entries; -+ -+ *index = hash; -+ if (airoha_ppe2_is_enabled(ppe->eth) && -+ hash >= ppe_num_stats_entries) -+ *index = *index - PPE_STATS_NUM_ENTRIES; - -- return hash >= PPE_STATS_NUM_ENTRIES ? hash - PPE1_STATS_NUM_ENTRIES -- : hash; -+ return 0; - } - - static void airoha_ppe_foe_flow_stat_entry_reset(struct airoha_ppe *ppe, -@@ -500,9 +536,13 @@ static void airoha_ppe_foe_flow_stat_ent - static void airoha_ppe_foe_flow_stats_reset(struct airoha_ppe *ppe, - struct airoha_npu *npu) - { -- int i; -+ int i, ppe_num_stats_entries; -+ -+ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); -+ if (ppe_num_stats_entries < 0) -+ return; - -- for (i = 0; i < PPE_STATS_NUM_ENTRIES; i++) -+ for (i = 0; i < ppe_num_stats_entries; i++) - airoha_ppe_foe_flow_stat_entry_reset(ppe, npu, i); - } - -@@ -513,10 +553,17 @@ static void airoha_ppe_foe_flow_stats_up - { - int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); - u32 index, pse_port, val, *data, *ib2, *meter; -+ int ppe_num_stats_entries; - u8 nbq; - -- index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); -- if (index >= PPE_STATS_NUM_ENTRIES) -+ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); -+ if (ppe_num_stats_entries < 0) -+ return; -+ -+ if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index)) -+ return; -+ -+ if (index >= ppe_num_stats_entries) - return; - - if (type == PPE_PKT_TYPE_BRIDGE) { -@@ -1158,11 +1205,19 @@ static int airoha_ppe_flow_offload_destr - void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, - struct airoha_foe_stats64 *stats) - { -- u32 index = airoha_ppe_foe_get_flow_stats_index(ppe, hash); - struct airoha_eth *eth = ppe->eth; -+ int ppe_num_stats_entries; - struct airoha_npu *npu; -+ u32 index; -+ -+ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); -+ if (ppe_num_stats_entries < 0) -+ return; - -- if (index >= PPE_STATS_NUM_ENTRIES) -+ if (airoha_ppe_foe_get_flow_stats_index(ppe, hash, &index)) -+ return; -+ -+ if (index >= ppe_num_stats_entries) - return; - - rcu_read_lock(); -@@ -1257,7 +1312,7 @@ static int airoha_ppe_offload_setup(stru - { - struct airoha_npu *npu = airoha_ppe_npu_get(eth); - struct airoha_ppe *ppe = eth->ppe; -- int err; -+ int err, ppe_num_stats_entries; - - if (IS_ERR(npu)) - return PTR_ERR(npu); -@@ -1266,9 +1321,10 @@ static int airoha_ppe_offload_setup(stru - if (err) - goto error_npu_put; - -- if (PPE_STATS_NUM_ENTRIES) { -+ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); -+ if (ppe_num_stats_entries > 0) { - err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma, -- PPE_STATS_NUM_ENTRIES); -+ ppe_num_stats_entries); - if (err) - goto error_npu_put; - } -@@ -1405,8 +1461,8 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); - - int airoha_ppe_init(struct airoha_eth *eth) - { -+ int foe_size, err, ppe_num_stats_entries; - struct airoha_ppe *ppe; -- int foe_size, err; - - ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); - if (!ppe) -@@ -1431,8 +1487,9 @@ int airoha_ppe_init(struct airoha_eth *e - if (!ppe->foe_flow) - return -ENOMEM; - -- foe_size = PPE_STATS_NUM_ENTRIES * sizeof(*ppe->foe_stats); -- if (foe_size) { -+ ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); -+ if (ppe_num_stats_entries > 0) { -+ foe_size = ppe_num_stats_entries * sizeof(*ppe->foe_stats); - ppe->foe_stats = dmam_alloc_coherent(eth->dev, foe_size, - &ppe->foe_stats_dma, - GFP_KERNEL); diff --git a/target/linux/airoha/patches-6.12/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch b/target/linux/airoha/patches-6.12/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch deleted file mode 100644 index 75c630d2e94..00000000000 --- a/target/linux/airoha/patches-6.12/099-03-v6.19-net-airoha-Add-airoha_eth_soc_data-struct.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 5863b4e065e2253ef05684f728a04e4972046bcb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:13 +0200 -Subject: [PATCH 03/12] net: airoha: Add airoha_eth_soc_data struct - -Introduce airoha_eth_soc_data struct to contain differences between -various SoC. Move XSI reset names in airoha_eth_soc_data. This is a -preliminary patch to enable AN7583 ethernet controller support in -airoha-eth driver. - -Co-developed-by: Christian Marangi -Signed-off-by: Christian Marangi -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-4-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 42 +++++++++++++++++++----- - drivers/net/ethernet/airoha/airoha_eth.h | 17 ++++++++-- - 2 files changed, 48 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1413,8 +1413,7 @@ static int airoha_hw_init(struct platfor - int err, i; - - /* disable xsi */ -- err = reset_control_bulk_assert(ARRAY_SIZE(eth->xsi_rsts), -- eth->xsi_rsts); -+ err = reset_control_bulk_assert(eth->soc->num_xsi_rsts, eth->xsi_rsts); - if (err) - return err; - -@@ -2948,6 +2947,7 @@ free_metadata_dst: - - static int airoha_probe(struct platform_device *pdev) - { -+ struct reset_control_bulk_data *xsi_rsts; - struct device_node *np; - struct airoha_eth *eth; - int i, err; -@@ -2956,6 +2956,10 @@ static int airoha_probe(struct platform_ - if (!eth) - return -ENOMEM; - -+ eth->soc = of_device_get_match_data(&pdev->dev); -+ if (!eth->soc) -+ return -EINVAL; -+ - eth->dev = &pdev->dev; - - err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32)); -@@ -2980,13 +2984,18 @@ static int airoha_probe(struct platform_ - return err; - } - -- eth->xsi_rsts[0].id = "xsi-mac"; -- eth->xsi_rsts[1].id = "hsi0-mac"; -- eth->xsi_rsts[2].id = "hsi1-mac"; -- eth->xsi_rsts[3].id = "hsi-mac"; -- eth->xsi_rsts[4].id = "xfp-mac"; -+ xsi_rsts = devm_kzalloc(eth->dev, -+ eth->soc->num_xsi_rsts * sizeof(*xsi_rsts), -+ GFP_KERNEL); -+ if (err) -+ return err; -+ -+ eth->xsi_rsts = xsi_rsts; -+ for (i = 0; i < eth->soc->num_xsi_rsts; i++) -+ eth->xsi_rsts[i].id = eth->soc->xsi_rsts_names[i]; -+ - err = devm_reset_control_bulk_get_exclusive(eth->dev, -- ARRAY_SIZE(eth->xsi_rsts), -+ eth->soc->num_xsi_rsts, - eth->xsi_rsts); - if (err) { - dev_err(eth->dev, "failed to get bulk xsi reset lines\n"); -@@ -3072,8 +3081,23 @@ static void airoha_remove(struct platfor - platform_set_drvdata(pdev, NULL); - } - -+static const char * const en7581_xsi_rsts_names[] = { -+ "xsi-mac", -+ "hsi0-mac", -+ "hsi1-mac", -+ "hsi-mac", -+ "xfp-mac", -+}; -+ -+static const struct airoha_eth_soc_data en7581_soc_data = { -+ .version = 0x7581, -+ .xsi_rsts_names = en7581_xsi_rsts_names, -+ .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), -+ .num_ppe = 2, -+}; -+ - static const struct of_device_id of_airoha_match[] = { -- { .compatible = "airoha,en7581-eth" }, -+ { .compatible = "airoha,en7581-eth", .data = &en7581_soc_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, of_airoha_match); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -21,7 +21,6 @@ - #define AIROHA_MAX_NUM_IRQ_BANKS 4 - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 --#define AIROHA_MAX_NUM_XSI_RSTS 5 - #define AIROHA_MAX_MTU 9216 - #define AIROHA_MAX_PACKET_SIZE 2048 - #define AIROHA_NUM_QOS_CHANNELS 4 -@@ -556,9 +555,18 @@ struct airoha_ppe { - struct dentry *debugfs_dir; - }; - -+struct airoha_eth_soc_data { -+ u16 version; -+ const char * const *xsi_rsts_names; -+ int num_xsi_rsts; -+ int num_ppe; -+}; -+ - struct airoha_eth { - struct device *dev; - -+ const struct airoha_eth_soc_data *soc; -+ - unsigned long state; - void __iomem *fe_regs; - -@@ -568,7 +576,7 @@ struct airoha_eth { - struct rhashtable flow_table; - - struct reset_control_bulk_data rsts[AIROHA_MAX_NUM_RSTS]; -- struct reset_control_bulk_data xsi_rsts[AIROHA_MAX_NUM_XSI_RSTS]; -+ struct reset_control_bulk_data *xsi_rsts; - - struct net_device *napi_dev; - -@@ -611,6 +619,11 @@ static inline bool airhoa_is_lan_gdm_por - return port->id == 1; - } - -+static inline bool airoha_is_7581(struct airoha_eth *eth) -+{ -+ return eth->soc->version == 0x7581; -+} -+ - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - diff --git a/target/linux/airoha/patches-6.12/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch b/target/linux/airoha/patches-6.12/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch deleted file mode 100644 index e6626674e82..00000000000 --- a/target/linux/airoha/patches-6.12/099-04-v6.19-net-airoha-Generalize-airoha_ppe2_is_enabled-routine.patch +++ /dev/null @@ -1,147 +0,0 @@ -From ef9449f080b61920cdc3d3106f8ffc2d9ba8b861 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:14 +0200 -Subject: [PATCH 04/12] net: airoha: Generalize airoha_ppe2_is_enabled routine - -Rename airoha_ppe2_is_enabled() in airoha_ppe_is_enabled() and -generalize it in order to check if each PPE module is enabled. -Rely on airoha_ppe_is_enabled routine to properly initialize PPE for -AN7583 SoC since AN7583 does not support PPE2. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-5-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 32 ++++++++++++++++-------- - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - drivers/net/ethernet/airoha/airoha_ppe.c | 17 +++++++------ - 3 files changed, 32 insertions(+), 18 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -297,8 +297,11 @@ static void airoha_fe_pse_ports_init(str - int q; - - all_rsv = airoha_fe_get_pse_all_rsv(eth); -- /* hw misses PPE2 oq rsv */ -- all_rsv += PSE_RSV_PAGES * pse_port_num_queues[FE_PSE_PORT_PPE2]; -+ if (airoha_ppe_is_enabled(eth, 1)) { -+ /* hw misses PPE2 oq rsv */ -+ all_rsv += PSE_RSV_PAGES * -+ pse_port_num_queues[FE_PSE_PORT_PPE2]; -+ } - airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); - - /* CMD1 */ -@@ -335,13 +338,17 @@ static void airoha_fe_pse_ports_init(str - for (q = 4; q < pse_port_num_queues[FE_PSE_PORT_CDM4]; q++) - airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q, - PSE_QUEUE_RSV_PAGES); -- /* PPE2 */ -- for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { -- if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, -- PSE_QUEUE_RSV_PAGES); -- else -- airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, q, 0); -+ if (airoha_ppe_is_enabled(eth, 1)) { -+ /* PPE2 */ -+ for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE2]; q++) { -+ if (q < pse_port_num_queues[FE_PSE_PORT_PPE2] / 2) -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, -+ q, -+ PSE_QUEUE_RSV_PAGES); -+ else -+ airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2, -+ q, 0); -+ } - } - /* GMD4 */ - for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++) -@@ -1788,8 +1795,11 @@ static int airoha_dev_init(struct net_de - airhoha_set_gdm2_loopback(port); - fallthrough; - case 2: -- pse_port = FE_PSE_PORT_PPE2; -- break; -+ if (airoha_ppe_is_enabled(eth, 1)) { -+ pse_port = FE_PSE_PORT_PPE2; -+ break; -+ } -+ fallthrough; - default: - pse_port = FE_PSE_PORT_PPE1; - break; ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -627,6 +627,7 @@ static inline bool airoha_is_7581(struct - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - -+bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); - void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, - u16 hash, bool rx_wlan); - int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -50,9 +50,12 @@ static int airoha_ppe_get_total_num_stat - return num_stats; - } - --static bool airoha_ppe2_is_enabled(struct airoha_eth *eth) -+bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index) - { -- return airoha_fe_rr(eth, REG_PPE_GLO_CFG(1)) & PPE_GLO_CFG_EN_MASK; -+ if (index >= eth->soc->num_ppe) -+ return false; -+ -+ return airoha_fe_rr(eth, REG_PPE_GLO_CFG(index)) & PPE_GLO_CFG_EN_MASK; - } - - static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) -@@ -120,7 +123,7 @@ static void airoha_ppe_hw_init(struct ai - AIROHA_MAX_MTU)); - } - -- if (airoha_ppe2_is_enabled(eth)) { -+ if (airoha_ppe_is_enabled(eth, 1)) { - sram_num_entries = PPE1_SRAM_NUM_ENTRIES; - sram_num_stats_entries = - airoha_ppe_get_num_stats_entries(ppe); -@@ -518,7 +521,7 @@ static int airoha_ppe_foe_get_flow_stats - return ppe_num_stats_entries; - - *index = hash; -- if (airoha_ppe2_is_enabled(ppe->eth) && -+ if (airoha_ppe_is_enabled(ppe->eth, 1) && - hash >= ppe_num_stats_entries) - *index = *index - PPE_STATS_NUM_ENTRIES; - -@@ -613,7 +616,7 @@ airoha_ppe_foe_get_entry_locked(struct a - u32 val; - int i; - -- ppe2 = airoha_ppe2_is_enabled(ppe->eth) && -+ ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && - hash >= PPE1_SRAM_NUM_ENTRIES; - airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), - FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | -@@ -691,7 +694,7 @@ static int airoha_ppe_foe_commit_entry(s - - if (hash < PPE_SRAM_NUM_ENTRIES) { - dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); -- bool ppe2 = airoha_ppe2_is_enabled(eth) && -+ bool ppe2 = airoha_ppe_is_enabled(eth, 1) && - hash >= PPE1_SRAM_NUM_ENTRIES; - - err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), -@@ -1286,7 +1289,7 @@ static int airoha_ppe_flush_sram_entries - int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; - struct airoha_foe_entry *hwe = ppe->foe; - -- if (airoha_ppe2_is_enabled(ppe->eth)) -+ if (airoha_ppe_is_enabled(ppe->eth, 1)) - sram_num_entries = sram_num_entries / 2; - - for (i = 0; i < sram_num_entries; i++) diff --git a/target/linux/airoha/patches-6.12/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch b/target/linux/airoha/patches-6.12/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch deleted file mode 100644 index 2382a21168c..00000000000 --- a/target/linux/airoha/patches-6.12/099-05-v6.19-net-airoha-ppe-Move-PPE-memory-info-in-airoha_eth_so.patch +++ /dev/null @@ -1,359 +0,0 @@ -From 5bd1d1fd48ea9f8300b211540d946899c7f96480 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:15 +0200 -Subject: [PATCH 05/12] net: airoha: ppe: Move PPE memory info in - airoha_eth_soc_data struct - -AN7583 SoC runs a single PPE device while EN7581 runs two of them. -Moreover PPE SRAM in AN7583 SoC is reduced to 8K (while SRAM is 16K on -EN7581). Take into account PPE memory layout during PPE configuration. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-6-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.h | 10 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 133 +++++++++--------- - .../net/ethernet/airoha/airoha_ppe_debugfs.c | 3 +- - 3 files changed, 70 insertions(+), 76 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -47,14 +47,9 @@ - #define QDMA_METER_IDX(_n) ((_n) & 0xff) - #define QDMA_METER_GROUP(_n) (((_n) >> 8) & 0x3) - --#define PPE_NUM 2 --#define PPE1_SRAM_NUM_ENTRIES (8 * 1024) --#define PPE_SRAM_NUM_ENTRIES (PPE_NUM * PPE1_SRAM_NUM_ENTRIES) --#define PPE1_STATS_NUM_ENTRIES (4 * 1024) --#define PPE_STATS_NUM_ENTRIES (PPE_NUM * PPE1_STATS_NUM_ENTRIES) -+#define PPE_SRAM_NUM_ENTRIES (8 * 1024) -+#define PPE_STATS_NUM_ENTRIES (4 * 1024) - #define PPE_DRAM_NUM_ENTRIES (16 * 1024) --#define PPE_NUM_ENTRIES (PPE_SRAM_NUM_ENTRIES + PPE_DRAM_NUM_ENTRIES) --#define PPE_HASH_MASK (PPE_NUM_ENTRIES - 1) - #define PPE_ENTRY_SIZE 80 - #define PPE_RAM_NUM_ENTRIES_SHIFT(_n) (__ffs((_n) >> 10)) - -@@ -634,6 +629,7 @@ int airoha_ppe_setup_tc_block_cb(struct - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); - void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); -+u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe); - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash); - void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash, ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -37,19 +37,36 @@ static int airoha_ppe_get_num_stats_entr - if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) - return -EOPNOTSUPP; - -- return PPE1_STATS_NUM_ENTRIES; -+ return PPE_STATS_NUM_ENTRIES; - } - - static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe) - { - int num_stats = airoha_ppe_get_num_stats_entries(ppe); - -- if (num_stats > 0) -- num_stats = num_stats * PPE_NUM; -+ if (num_stats > 0) { -+ struct airoha_eth *eth = ppe->eth; -+ -+ num_stats = num_stats * eth->soc->num_ppe; -+ } - - return num_stats; - } - -+static u32 airoha_ppe_get_total_sram_num_entries(struct airoha_ppe *ppe) -+{ -+ struct airoha_eth *eth = ppe->eth; -+ -+ return PPE_SRAM_NUM_ENTRIES * eth->soc->num_ppe; -+} -+ -+u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe) -+{ -+ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); -+ -+ return sram_num_entries + PPE_DRAM_NUM_ENTRIES; -+} -+ - bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index) - { - if (index >= eth->soc->num_ppe) -@@ -67,14 +84,22 @@ static u32 airoha_ppe_get_timestamp(stru - - static void airoha_ppe_hw_init(struct airoha_ppe *ppe) - { -- u32 sram_tb_size, sram_num_entries, dram_num_entries; -+ u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries; -+ u32 sram_tb_size, dram_num_entries; - struct airoha_eth *eth = ppe->eth; - int i, sram_num_stats_entries; - -- sram_tb_size = PPE_SRAM_NUM_ENTRIES * sizeof(struct airoha_foe_entry); -+ sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); -+ sram_tb_size = sram_num_entries * sizeof(struct airoha_foe_entry); - dram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(PPE_DRAM_NUM_ENTRIES); - -- for (i = 0; i < PPE_NUM; i++) { -+ sram_num_stats_entries = airoha_ppe_get_num_stats_entries(ppe); -+ if (sram_num_stats_entries > 0) -+ sram_ppe_num_data_entries -= sram_num_stats_entries; -+ sram_ppe_num_data_entries = -+ PPE_RAM_NUM_ENTRIES_SHIFT(sram_ppe_num_data_entries); -+ -+ for (i = 0; i < eth->soc->num_ppe; i++) { - int p; - - airoha_fe_wr(eth, REG_PPE_TB_BASE(i), -@@ -106,10 +131,16 @@ static void airoha_ppe_hw_init(struct ai - - airoha_fe_rmw(eth, REG_PPE_TB_CFG(i), - PPE_TB_CFG_SEARCH_MISS_MASK | -+ PPE_SRAM_TB_NUM_ENTRY_MASK | -+ PPE_DRAM_TB_NUM_ENTRY_MASK | - PPE_TB_CFG_KEEPALIVE_MASK | - PPE_TB_ENTRY_SIZE_MASK, - FIELD_PREP(PPE_TB_CFG_SEARCH_MISS_MASK, 3) | -- FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0)); -+ FIELD_PREP(PPE_TB_ENTRY_SIZE_MASK, 0) | -+ FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, -+ sram_ppe_num_data_entries) | -+ FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, -+ dram_num_entries)); - - airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); - -@@ -122,45 +153,6 @@ static void airoha_ppe_hw_init(struct ai - FIELD_PREP(FP1_EGRESS_MTU_MASK, - AIROHA_MAX_MTU)); - } -- -- if (airoha_ppe_is_enabled(eth, 1)) { -- sram_num_entries = PPE1_SRAM_NUM_ENTRIES; -- sram_num_stats_entries = -- airoha_ppe_get_num_stats_entries(ppe); -- if (sram_num_stats_entries > 0) -- sram_num_entries -= sram_num_stats_entries; -- sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); -- -- airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), -- PPE_SRAM_TB_NUM_ENTRY_MASK | -- PPE_DRAM_TB_NUM_ENTRY_MASK, -- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, -- sram_num_entries) | -- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, -- dram_num_entries)); -- airoha_fe_rmw(eth, REG_PPE_TB_CFG(1), -- PPE_SRAM_TB_NUM_ENTRY_MASK | -- PPE_DRAM_TB_NUM_ENTRY_MASK, -- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, -- sram_num_entries) | -- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, -- dram_num_entries)); -- } else { -- sram_num_entries = PPE_SRAM_NUM_ENTRIES; -- sram_num_stats_entries = -- airoha_ppe_get_total_num_stats_entries(ppe); -- if (sram_num_stats_entries > 0) -- sram_num_entries -= sram_num_stats_entries; -- sram_num_entries = PPE_RAM_NUM_ENTRIES_SHIFT(sram_num_entries); -- -- airoha_fe_rmw(eth, REG_PPE_TB_CFG(0), -- PPE_SRAM_TB_NUM_ENTRY_MASK | -- PPE_DRAM_TB_NUM_ENTRY_MASK, -- FIELD_PREP(PPE_SRAM_TB_NUM_ENTRY_MASK, -- sram_num_entries) | -- FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, -- dram_num_entries)); -- } - } - - static void airoha_ppe_flow_mangle_eth(const struct flow_action_entry *act, void *eth) -@@ -459,9 +451,11 @@ static int airoha_ppe_foe_entry_set_ipv6 - return 0; - } - --static u32 airoha_ppe_foe_get_entry_hash(struct airoha_foe_entry *hwe) -+static u32 airoha_ppe_foe_get_entry_hash(struct airoha_ppe *ppe, -+ struct airoha_foe_entry *hwe) - { - int type = FIELD_GET(AIROHA_FOE_IB1_BIND_PACKET_TYPE, hwe->ib1); -+ u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1; - u32 hash, hv1, hv2, hv3; - - switch (type) { -@@ -499,14 +493,14 @@ static u32 airoha_ppe_foe_get_entry_hash - case PPE_PKT_TYPE_IPV6_6RD: - default: - WARN_ON_ONCE(1); -- return PPE_HASH_MASK; -+ return ppe_hash_mask; - } - - hash = (hv1 & hv2) | ((~hv1) & hv3); - hash = (hash >> 24) | ((hash & 0xffffff) << 8); - hash ^= hv1 ^ hv2 ^ hv3; - hash ^= hash >> 16; -- hash &= PPE_NUM_ENTRIES - 1; -+ hash &= ppe_hash_mask; - - return hash; - } -@@ -607,9 +601,11 @@ static void airoha_ppe_foe_flow_stats_up - static struct airoha_foe_entry * - airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash) - { -+ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); -+ - lockdep_assert_held(&ppe_lock); - -- if (hash < PPE_SRAM_NUM_ENTRIES) { -+ if (hash < sram_num_entries) { - u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); - struct airoha_eth *eth = ppe->eth; - bool ppe2; -@@ -617,7 +613,7 @@ airoha_ppe_foe_get_entry_locked(struct a - int i; - - ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && -- hash >= PPE1_SRAM_NUM_ENTRIES; -+ hash >= PPE_SRAM_NUM_ENTRIES; - airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), - FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | - PPE_SRAM_CTRL_REQ_MASK); -@@ -668,6 +664,7 @@ static int airoha_ppe_foe_commit_entry(s - struct airoha_foe_entry *e, - u32 hash, bool rx_wlan) - { -+ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); - struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); - u32 ts = airoha_ppe_get_timestamp(ppe); - struct airoha_eth *eth = ppe->eth; -@@ -692,10 +689,10 @@ static int airoha_ppe_foe_commit_entry(s - if (!rx_wlan) - airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); - -- if (hash < PPE_SRAM_NUM_ENTRIES) { -+ if (hash < sram_num_entries) { - dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); - bool ppe2 = airoha_ppe_is_enabled(eth, 1) && -- hash >= PPE1_SRAM_NUM_ENTRIES; -+ hash >= PPE_SRAM_NUM_ENTRIES; - - err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), - hash, ppe2); -@@ -822,7 +819,7 @@ static void airoha_ppe_foe_insert_entry( - if (state == AIROHA_FOE_STATE_BIND) - goto unlock; - -- index = airoha_ppe_foe_get_entry_hash(hwe); -+ index = airoha_ppe_foe_get_entry_hash(ppe, hwe); - hlist_for_each_entry_safe(e, n, &ppe->foe_flow[index], list) { - if (e->type == FLOW_TYPE_L2_SUBFLOW) { - state = FIELD_GET(AIROHA_FOE_IB1_BIND_STATE, hwe->ib1); -@@ -882,7 +879,7 @@ static int airoha_ppe_foe_flow_commit_en - if (type == PPE_PKT_TYPE_BRIDGE) - return airoha_ppe_foe_l2_flow_commit_entry(ppe, e); - -- hash = airoha_ppe_foe_get_entry_hash(&e->data); -+ hash = airoha_ppe_foe_get_entry_hash(ppe, &e->data); - e->type = FLOW_TYPE_L4; - e->hash = 0xffff; - -@@ -1286,17 +1283,15 @@ static int airoha_ppe_flow_offload_cmd(s - static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, - struct airoha_npu *npu) - { -- int i, sram_num_entries = PPE_SRAM_NUM_ENTRIES; -+ u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); - struct airoha_foe_entry *hwe = ppe->foe; -+ int i; - -- if (airoha_ppe_is_enabled(ppe->eth, 1)) -- sram_num_entries = sram_num_entries / 2; -- -- for (i = 0; i < sram_num_entries; i++) -+ for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++) - memset(&hwe[i], 0, sizeof(*hwe)); - - return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, -- PPE_SRAM_NUM_ENTRIES); -+ sram_num_entries); - } - - static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) -@@ -1372,9 +1367,10 @@ void airoha_ppe_check_skb(struct airoha_ - u16 hash, bool rx_wlan) - { - struct airoha_ppe *ppe = dev->priv; -+ u32 ppe_hash_mask = airoha_ppe_get_total_num_entries(ppe) - 1; - u16 now, diff; - -- if (hash > PPE_HASH_MASK) -+ if (hash > ppe_hash_mask) - return; - - now = (u16)jiffies; -@@ -1465,6 +1461,7 @@ EXPORT_SYMBOL_GPL(airoha_ppe_put_dev); - int airoha_ppe_init(struct airoha_eth *eth) - { - int foe_size, err, ppe_num_stats_entries; -+ u32 ppe_num_entries; - struct airoha_ppe *ppe; - - ppe = devm_kzalloc(eth->dev, sizeof(*ppe), GFP_KERNEL); -@@ -1474,18 +1471,18 @@ int airoha_ppe_init(struct airoha_eth *e - ppe->dev.ops.setup_tc_block_cb = airoha_ppe_setup_tc_block_cb; - ppe->dev.ops.check_skb = airoha_ppe_check_skb; - ppe->dev.priv = ppe; -+ ppe->eth = eth; -+ eth->ppe = ppe; - -- foe_size = PPE_NUM_ENTRIES * sizeof(struct airoha_foe_entry); -+ ppe_num_entries = airoha_ppe_get_total_num_entries(ppe); -+ foe_size = ppe_num_entries * sizeof(struct airoha_foe_entry); - ppe->foe = dmam_alloc_coherent(eth->dev, foe_size, &ppe->foe_dma, - GFP_KERNEL); - if (!ppe->foe) - return -ENOMEM; - -- ppe->eth = eth; -- eth->ppe = ppe; -- - ppe->foe_flow = devm_kzalloc(eth->dev, -- PPE_NUM_ENTRIES * sizeof(*ppe->foe_flow), -+ ppe_num_entries * sizeof(*ppe->foe_flow), - GFP_KERNEL); - if (!ppe->foe_flow) - return -ENOMEM; -@@ -1500,7 +1497,7 @@ int airoha_ppe_init(struct airoha_eth *e - return -ENOMEM; - } - -- ppe->foe_check_time = devm_kzalloc(eth->dev, PPE_NUM_ENTRIES, -+ ppe->foe_check_time = devm_kzalloc(eth->dev, ppe_num_entries, - GFP_KERNEL); - if (!ppe->foe_check_time) - return -ENOMEM; ---- a/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe_debugfs.c -@@ -53,9 +53,10 @@ static int airoha_ppe_debugfs_foe_show(s - [AIROHA_FOE_STATE_FIN] = "FIN", - }; - struct airoha_ppe *ppe = m->private; -+ u32 ppe_num_entries = airoha_ppe_get_total_num_entries(ppe); - int i; - -- for (i = 0; i < PPE_NUM_ENTRIES; i++) { -+ for (i = 0; i < ppe_num_entries; i++) { - const char *state_str, *type_str = "UNKNOWN"; - void *src_addr = NULL, *dest_addr = NULL; - u16 *src_port = NULL, *dest_port = NULL; diff --git a/target/linux/airoha/patches-6.12/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch b/target/linux/airoha/patches-6.12/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch deleted file mode 100644 index 18b92fb50df..00000000000 --- a/target/linux/airoha/patches-6.12/099-06-v6.19-net-airoha-ppe-Remove-airoha_ppe_is_enabled-where-no.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 41139125f5c70e0f66f0cc4ac1b3a62f5801ab42 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:16 +0200 -Subject: [PATCH 06/12] net: airoha: ppe: Remove airoha_ppe_is_enabled() where - not necessary - -Now each PPE has always PPE_STATS_NUM_ENTRIES entries so we do not need -to run airoha_ppe_is_enabled routine to check if the hash refers to -PPE1 or PPE2. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-7-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 13 ++++--------- - 1 file changed, 4 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -514,10 +514,8 @@ static int airoha_ppe_foe_get_flow_stats - if (ppe_num_stats_entries < 0) - return ppe_num_stats_entries; - -- *index = hash; -- if (airoha_ppe_is_enabled(ppe->eth, 1) && -- hash >= ppe_num_stats_entries) -- *index = *index - PPE_STATS_NUM_ENTRIES; -+ *index = hash >= ppe_num_stats_entries ? hash - PPE_STATS_NUM_ENTRIES -+ : hash; - - return 0; - } -@@ -607,13 +605,11 @@ airoha_ppe_foe_get_entry_locked(struct a - - if (hash < sram_num_entries) { - u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); -+ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; - struct airoha_eth *eth = ppe->eth; -- bool ppe2; - u32 val; - int i; - -- ppe2 = airoha_ppe_is_enabled(ppe->eth, 1) && -- hash >= PPE_SRAM_NUM_ENTRIES; - airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), - FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | - PPE_SRAM_CTRL_REQ_MASK); -@@ -691,8 +687,7 @@ static int airoha_ppe_foe_commit_entry(s - - if (hash < sram_num_entries) { - dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); -- bool ppe2 = airoha_ppe_is_enabled(eth, 1) && -- hash >= PPE_SRAM_NUM_ENTRIES; -+ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; - - err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), - hash, ppe2); diff --git a/target/linux/airoha/patches-6.12/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch b/target/linux/airoha/patches-6.12/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch deleted file mode 100644 index 60b4ee1e448..00000000000 --- a/target/linux/airoha/patches-6.12/099-07-v6.19-net-airoha-ppe-Configure-SRAM-PPE-entries-via-the-cp.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 306b78f5035af4bd011753c5a6b12812515caa6c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:17 +0200 -Subject: [PATCH 07/12] net: airoha: ppe: Configure SRAM PPE entries via the - cpu - -Introduce airoha_ppe_foe_commit_sram_entry routine in order to configure -the SRAM PPE entries directly via the CPU instead of using the NPU APIs. -This is a preliminary patch to enable netfilter flowtable hw offload for -AN7583 SoC. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-8-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 30 ++++++++++++++++++------ - 1 file changed, 23 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -656,6 +656,27 @@ static bool airoha_ppe_foe_compare_entry - return !memcmp(&e->data.d, &hwe->d, len - sizeof(hwe->ib1)); - } - -+static int airoha_ppe_foe_commit_sram_entry(struct airoha_ppe *ppe, u32 hash) -+{ -+ struct airoha_foe_entry *hwe = ppe->foe + hash * sizeof(*hwe); -+ bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; -+ u32 *ptr = (u32 *)hwe, val; -+ int i; -+ -+ for (i = 0; i < sizeof(*hwe) / sizeof(*ptr); i++) -+ airoha_fe_wr(ppe->eth, REG_PPE_RAM_ENTRY(ppe2, i), ptr[i]); -+ -+ wmb(); -+ airoha_fe_wr(ppe->eth, REG_PPE_RAM_CTRL(ppe2), -+ FIELD_PREP(PPE_SRAM_CTRL_ENTRY_MASK, hash) | -+ PPE_SRAM_CTRL_WR_MASK | PPE_SRAM_CTRL_REQ_MASK); -+ -+ return read_poll_timeout_atomic(airoha_fe_rr, val, -+ val & PPE_SRAM_CTRL_ACK_MASK, -+ 10, 100, false, ppe->eth, -+ REG_PPE_RAM_CTRL(ppe2)); -+} -+ - static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe, - struct airoha_foe_entry *e, - u32 hash, bool rx_wlan) -@@ -685,13 +706,8 @@ static int airoha_ppe_foe_commit_entry(s - if (!rx_wlan) - airoha_ppe_foe_flow_stats_update(ppe, npu, hwe, hash); - -- if (hash < sram_num_entries) { -- dma_addr_t addr = ppe->foe_dma + hash * sizeof(*hwe); -- bool ppe2 = hash >= PPE_SRAM_NUM_ENTRIES; -- -- err = npu->ops.ppe_foe_commit_entry(npu, addr, sizeof(*hwe), -- hash, ppe2); -- } -+ if (hash < sram_num_entries) -+ err = airoha_ppe_foe_commit_sram_entry(ppe, hash); - unlock: - rcu_read_unlock(); - diff --git a/target/linux/airoha/patches-6.12/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch b/target/linux/airoha/patches-6.12/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch deleted file mode 100644 index 24ecccabc8d..00000000000 --- a/target/linux/airoha/patches-6.12/099-08-v6.19-net-airoha-ppe-Flush-PPE-SRAM-table-during-PPE-setup.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 620d7b91aadbd4eb930895b07e34f0a155a9d3c1 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:18 +0200 -Subject: [PATCH 08/12] net: airoha: ppe: Flush PPE SRAM table during PPE setup - -Rely on airoha_ppe_foe_commit_sram_entry routine to flush SRAM PPE table -entries. This patch allow moving PPE SRAM flush during PPE setup and -avoid dumping uninitialized values via the debugfs if no entries are -offloaded yet. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-9-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 24 ++++++++++++++---------- - 1 file changed, 14 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -1291,18 +1291,22 @@ static int airoha_ppe_flow_offload_cmd(s - return -EOPNOTSUPP; - } - --static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe, -- struct airoha_npu *npu) -+static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe) - { - u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe); - struct airoha_foe_entry *hwe = ppe->foe; -- int i; -+ int i, err = 0; -+ -+ for (i = 0; i < sram_num_entries; i++) { -+ int err; - -- for (i = 0; i < PPE_SRAM_NUM_ENTRIES; i++) - memset(&hwe[i], 0, sizeof(*hwe)); -+ err = airoha_ppe_foe_commit_sram_entry(ppe, i); -+ if (err) -+ break; -+ } - -- return npu->ops.ppe_flush_sram_entries(npu, ppe->foe_dma, -- sram_num_entries); -+ return err; - } - - static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth) -@@ -1339,10 +1343,6 @@ static int airoha_ppe_offload_setup(stru - } - - airoha_ppe_hw_init(ppe); -- err = airoha_ppe_flush_sram_entries(ppe, npu); -- if (err) -- goto error_npu_put; -- - airoha_ppe_foe_flow_stats_reset(ppe, npu); - - rcu_assign_pointer(eth->npu, npu); -@@ -1513,6 +1513,10 @@ int airoha_ppe_init(struct airoha_eth *e - if (!ppe->foe_check_time) - return -ENOMEM; - -+ err = airoha_ppe_flush_sram_entries(ppe); -+ if (err) -+ return err; -+ - err = rhashtable_init(ð->flow_table, &airoha_flow_table_params); - if (err) - return err; diff --git a/target/linux/airoha/patches-6.12/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch b/target/linux/airoha/patches-6.12/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch deleted file mode 100644 index d6fc01a4471..00000000000 --- a/target/linux/airoha/patches-6.12/099-09-v6.19-net-airoha-Select-default-ppe-cpu-port-in-airoha_dev.patch +++ /dev/null @@ -1,91 +0,0 @@ -From c71a7a861ef02aa2bebb18c2f3385aa3f19094e0 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:19 +0200 -Subject: [PATCH 09/12] net: airoha: Select default ppe cpu port in - airoha_dev_init() - -Select the PPE default cpu port in airoha_dev_init routine. -This patch allows to distribute the load between the two available cpu -ports (FE_PSE_PORT_CDM1 and FE_PSE_PORT_CDM2) if the device is running a -single PPE module (e.g. 7583) selecting the cpu port based on the use -QDMA device. For multi-PPE device (e.g. 7581) assign FE_PSE_PORT_CDM1 to -PPE1 and FE_PSE_PORT_CDM2 to PPE2. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-10-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 38 ++++++++++-------------- - 1 file changed, 16 insertions(+), 22 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -531,25 +531,6 @@ static int airoha_fe_init(struct airoha_ - /* disable IFC by default */ - airoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK); - -- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), -- FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM1) | -- FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM1) | -- FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM1) | -- FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM1) | -- FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM1) | -- FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM1) | -- FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM1) | -- FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM1)); -- airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(1), -- FIELD_PREP(DFT_CPORT_MASK(7), FE_PSE_PORT_CDM2) | -- FIELD_PREP(DFT_CPORT_MASK(6), FE_PSE_PORT_CDM2) | -- FIELD_PREP(DFT_CPORT_MASK(5), FE_PSE_PORT_CDM2) | -- FIELD_PREP(DFT_CPORT_MASK(4), FE_PSE_PORT_CDM2) | -- FIELD_PREP(DFT_CPORT_MASK(3), FE_PSE_PORT_CDM2) | -- FIELD_PREP(DFT_CPORT_MASK(2), FE_PSE_PORT_CDM2) | -- FIELD_PREP(DFT_CPORT_MASK(1), FE_PSE_PORT_CDM2) | -- FIELD_PREP(DFT_CPORT_MASK(0), FE_PSE_PORT_CDM2)); -- - /* enable 1:N vlan action, init vlan table */ - airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK); - -@@ -1782,8 +1763,10 @@ static void airhoha_set_gdm2_loopback(st - static int airoha_dev_init(struct net_device *dev) - { - struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_eth *eth = port->qdma->eth; -- u32 pse_port; -+ struct airoha_qdma *qdma = port->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ u32 pse_port, fe_cpu_port; -+ u8 ppe_id; - - airoha_set_macaddr(port, dev->dev_addr); - -@@ -1796,16 +1779,27 @@ static int airoha_dev_init(struct net_de - fallthrough; - case 2: - if (airoha_ppe_is_enabled(eth, 1)) { -+ /* For PPE2 always use secondary cpu port. */ -+ fe_cpu_port = FE_PSE_PORT_CDM2; - pse_port = FE_PSE_PORT_PPE2; - break; - } - fallthrough; -- default: -+ default: { -+ u8 qdma_id = qdma - ð->qdma[0]; -+ -+ /* For PPE1 select cpu port according to the running QDMA. */ -+ fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; - pse_port = FE_PSE_PORT_PPE1; - break; - } -+ } - - airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); -+ ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0; -+ airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), -+ DFT_CPORT_MASK(port->id), -+ fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id))); - - return 0; - } diff --git a/target/linux/airoha/patches-6.12/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch b/target/linux/airoha/patches-6.12/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch deleted file mode 100644 index 597946f932d..00000000000 --- a/target/linux/airoha/patches-6.12/099-10-v6.19-net-airoha-Refactor-src-port-configuration-in-airhoh.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 9d5b5219f672c80bed4d4e15f0068e648cdca43b Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:20 +0200 -Subject: [PATCH 10/12] net: airoha: Refactor src port configuration in - airhoha_set_gdm2_loopback - -AN7583 chipset relies on different definitions for source-port -identifier used for hw offloading. In order to support hw offloading -in AN7583 controller, refactor src port configuration in -airhoha_set_gdm2_loopback routine and introduce get_src_port_id -callback. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-11-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 82 ++++++++++++++++------- - drivers/net/ethernet/airoha/airoha_eth.h | 18 +++-- - drivers/net/ethernet/airoha/airoha_regs.h | 6 +- - 3 files changed, 73 insertions(+), 33 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1708,13 +1708,17 @@ static int airoha_dev_set_macaddr(struct - return 0; - } - --static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) -+static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) - { -- u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; -+ u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0; - struct airoha_eth *eth = port->qdma->eth; -- u32 chan = port->id == 3 ? 4 : 0; -+ /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ -+ u32 nbq = port->id == AIROHA_GDM3_IDX ? 4 : 0; -+ int src_port; - - /* Forward the traffic to the proper GDM port */ -+ pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 -+ : FE_PSE_PORT_GDM4; - airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); - airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); - -@@ -1735,29 +1739,25 @@ static void airhoha_set_gdm2_loopback(st - airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); - airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); - -- if (port->id == 3) { -- /* FIXME: handle XSI_PCE1_PORT */ -- airoha_fe_rmw(eth, REG_FE_WAN_PORT, -- WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, -- FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); -- airoha_fe_rmw(eth, -- REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3), -- SP_CPORT_PCIE0_MASK, -- FIELD_PREP(SP_CPORT_PCIE0_MASK, -- FE_PSE_PORT_CDM2)); -- } else { -- /* FIXME: handle XSI_USB_PORT */ -+ src_port = eth->soc->ops.get_src_port_id(port, nbq); -+ if (src_port < 0) -+ return src_port; -+ -+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, -+ WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, -+ FIELD_PREP(WAN0_MASK, src_port)); -+ val = src_port & SP_CPORT_DFT_MASK; -+ airoha_fe_rmw(eth, -+ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)), -+ SP_CPORT_MASK(val), -+ FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); -+ -+ if (port->id != AIROHA_GDM3_IDX) - airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, - FC_ID_OF_SRC_PORT24_MASK, - FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); -- airoha_fe_rmw(eth, REG_FE_WAN_PORT, -- WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, -- FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT)); -- airoha_fe_rmw(eth, -- REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3), -- SP_CPORT_ETH_MASK, -- FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2)); -- } -+ -+ return 0; - } - - static int airoha_dev_init(struct net_device *dev) -@@ -1774,8 +1774,13 @@ static int airoha_dev_init(struct net_de - case 3: - case 4: - /* If GDM2 is active we can't enable loopback */ -- if (!eth->ports[1]) -- airhoha_set_gdm2_loopback(port); -+ if (!eth->ports[1]) { -+ int err; -+ -+ err = airhoha_set_gdm2_loopback(port); -+ if (err) -+ return err; -+ } - fallthrough; - case 2: - if (airoha_ppe_is_enabled(eth, 1)) { -@@ -3093,11 +3098,38 @@ static const char * const en7581_xsi_rst - "xfp-mac", - }; - -+static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) -+{ -+ switch (port->id) { -+ case 3: -+ /* 7581 SoC supports PCIe serdes on GDM3 port */ -+ if (nbq == 4) -+ return HSGMII_LAN_7581_PCIE0_SRCPORT; -+ if (nbq == 5) -+ return HSGMII_LAN_7581_PCIE1_SRCPORT; -+ break; -+ case 4: -+ /* 7581 SoC supports eth and usb serdes on GDM4 port */ -+ if (!nbq) -+ return HSGMII_LAN_7581_ETH_SRCPORT; -+ if (nbq == 1) -+ return HSGMII_LAN_7581_USB_SRCPORT; -+ break; -+ default: -+ break; -+ } -+ -+ return -EINVAL; -+} -+ - static const struct airoha_eth_soc_data en7581_soc_data = { - .version = 0x7581, - .xsi_rsts_names = en7581_xsi_rsts_names, - .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), - .num_ppe = 2, -+ .ops = { -+ .get_src_port_id = airoha_en7581_get_src_port_id, -+ }, - }; - - static const struct of_device_id of_airoha_match[] = { ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -67,10 +67,10 @@ enum { - }; - - enum { -- HSGMII_LAN_PCIE0_SRCPORT = 0x16, -- HSGMII_LAN_PCIE1_SRCPORT, -- HSGMII_LAN_ETH_SRCPORT, -- HSGMII_LAN_USB_SRCPORT, -+ HSGMII_LAN_7581_PCIE0_SRCPORT = 0x16, -+ HSGMII_LAN_7581_PCIE1_SRCPORT, -+ HSGMII_LAN_7581_ETH_SRCPORT, -+ HSGMII_LAN_7581_USB_SRCPORT, - }; - - enum { -@@ -99,6 +99,13 @@ enum { - CRSN_25 = 0x19, - }; - -+enum airoha_gdm_index { -+ AIROHA_GDM1_IDX = 1, -+ AIROHA_GDM2_IDX = 2, -+ AIROHA_GDM3_IDX = 3, -+ AIROHA_GDM4_IDX = 4, -+}; -+ - enum { - FE_PSE_PORT_CDM1, - FE_PSE_PORT_GDM1, -@@ -555,6 +562,9 @@ struct airoha_eth_soc_data { - const char * const *xsi_rsts_names; - int num_xsi_rsts; - int num_ppe; -+ struct { -+ int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq); -+ } ops; - }; - - struct airoha_eth { ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -383,10 +383,8 @@ - #define REG_MC_VLAN_DATA 0x2108 - - #define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2)) --#define SP_CPORT_PCIE1_MASK GENMASK(31, 28) --#define SP_CPORT_PCIE0_MASK GENMASK(27, 24) --#define SP_CPORT_USB_MASK GENMASK(7, 4) --#define SP_CPORT_ETH_MASK GENMASK(7, 4) -+#define SP_CPORT_DFT_MASK GENMASK(2, 0) -+#define SP_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) - - #define REG_SRC_PORT_FC_MAP6 0x2298 - #define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) diff --git a/target/linux/airoha/patches-6.12/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch b/target/linux/airoha/patches-6.12/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch deleted file mode 100644 index 93e7f5e592c..00000000000 --- a/target/linux/airoha/patches-6.12/099-11-v6.19-net-airoha-ppe-Do-not-use-magic-numbers-in-airoha_pp.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 63f283d36b1fb06b55ae609a1f679544f5f66057 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:21 +0200 -Subject: [PATCH 11/12] net: airoha: ppe: Do not use magic numbers in - airoha_ppe_foe_get_entry_locked() - -Explicit the size of entries pointed by hwe pointer in -airoha_ppe_foe_get_entry_locked routine - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-12-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -619,7 +619,8 @@ airoha_ppe_foe_get_entry_locked(struct a - REG_PPE_RAM_CTRL(ppe2))) - return NULL; - -- for (i = 0; i < sizeof(struct airoha_foe_entry) / 4; i++) -+ for (i = 0; i < sizeof(struct airoha_foe_entry) / sizeof(*hwe); -+ i++) - hwe[i] = airoha_fe_rr(eth, - REG_PPE_RAM_ENTRY(ppe2, i)); - } diff --git a/target/linux/airoha/patches-6.12/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch b/target/linux/airoha/patches-6.12/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch deleted file mode 100644 index b9812ef455b..00000000000 --- a/target/linux/airoha/patches-6.12/099-12-v6.19-net-airoha-Add-AN7583-SoC-support.patch +++ /dev/null @@ -1,185 +0,0 @@ -From e4e5ce823bdd4601bd75ae7c206ae35e7c2fa60b Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 11:06:22 +0200 -Subject: [PATCH 12/12] net: airoha: Add AN7583 SoC support - -Introduce support for AN7583 ethernet controller to airoha-eth dirver. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-13-f28319666667@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 68 ++++++++++++++++++++++-- - drivers/net/ethernet/airoha/airoha_eth.h | 11 ++++ - drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++ - 3 files changed, 77 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1710,10 +1710,8 @@ static int airoha_dev_set_macaddr(struct - - static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) - { -- u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0; - struct airoha_eth *eth = port->qdma->eth; -- /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ -- u32 nbq = port->id == AIROHA_GDM3_IDX ? 4 : 0; -+ u32 val, pse_port, chan, nbq; - int src_port; - - /* Forward the traffic to the proper GDM port */ -@@ -1725,6 +1723,8 @@ static int airhoha_set_gdm2_loopback(str - /* Enable GDM2 loopback */ - airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); - airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); -+ -+ chan = port->id == AIROHA_GDM3_IDX ? airoha_is_7581(eth) ? 4 : 3 : 0; - airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), - LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, - FIELD_PREP(LPBK_CHAN_MASK, chan) | -@@ -1739,6 +1739,8 @@ static int airhoha_set_gdm2_loopback(str - airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); - airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); - -+ /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ -+ nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; - src_port = eth->soc->ops.get_src_port_id(port, nbq); - if (src_port < 0) - return src_port; -@@ -1752,7 +1754,7 @@ static int airhoha_set_gdm2_loopback(str - SP_CPORT_MASK(val), - FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); - -- if (port->id != AIROHA_GDM3_IDX) -+ if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth)) - airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, - FC_ID_OF_SRC_PORT24_MASK, - FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); -@@ -1921,6 +1923,22 @@ static bool airoha_dev_tx_queue_busy(str - return index >= tail; - } - -+static int airoha_get_fe_port(struct airoha_gdm_port *port) -+{ -+ struct airoha_qdma *qdma = port->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ -+ switch (eth->soc->version) { -+ case 0x7583: -+ return port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 -+ : port->id; -+ case 0x7581: -+ default: -+ return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4 -+ : port->id; -+ } -+} -+ - static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, - struct net_device *dev) - { -@@ -1961,7 +1979,7 @@ static netdev_tx_t airoha_dev_xmit(struc - } - } - -- fport = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; -+ fport = airoha_get_fe_port(port); - msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | - FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); - -@@ -3122,6 +3140,35 @@ static int airoha_en7581_get_src_port_id - return -EINVAL; - } - -+static const char * const an7583_xsi_rsts_names[] = { -+ "xsi-mac", -+ "hsi0-mac", -+ "hsi1-mac", -+ "xfp-mac", -+}; -+ -+static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq) -+{ -+ switch (port->id) { -+ case 3: -+ /* 7583 SoC supports eth serdes on GDM3 port */ -+ if (!nbq) -+ return HSGMII_LAN_7583_ETH_SRCPORT; -+ break; -+ case 4: -+ /* 7583 SoC supports PCIe and USB serdes on GDM4 port */ -+ if (!nbq) -+ return HSGMII_LAN_7583_PCIE_SRCPORT; -+ if (nbq == 1) -+ return HSGMII_LAN_7583_USB_SRCPORT; -+ break; -+ default: -+ break; -+ } -+ -+ return -EINVAL; -+} -+ - static const struct airoha_eth_soc_data en7581_soc_data = { - .version = 0x7581, - .xsi_rsts_names = en7581_xsi_rsts_names, -@@ -3132,8 +3179,19 @@ static const struct airoha_eth_soc_data - }, - }; - -+static const struct airoha_eth_soc_data an7583_soc_data = { -+ .version = 0x7583, -+ .xsi_rsts_names = an7583_xsi_rsts_names, -+ .num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names), -+ .num_ppe = 1, -+ .ops = { -+ .get_src_port_id = airoha_an7583_get_src_port_id, -+ }, -+}; -+ - static const struct of_device_id of_airoha_match[] = { - { .compatible = "airoha,en7581-eth", .data = &en7581_soc_data }, -+ { .compatible = "airoha,an7583-eth", .data = &an7583_soc_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, of_airoha_match); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -74,6 +74,12 @@ enum { - }; - - enum { -+ HSGMII_LAN_7583_ETH_SRCPORT = 0x16, -+ HSGMII_LAN_7583_PCIE_SRCPORT = 0x18, -+ HSGMII_LAN_7583_USB_SRCPORT, -+}; -+ -+enum { - XSI_PCIE0_VIP_PORT_MASK = BIT(22), - XSI_PCIE1_VIP_PORT_MASK = BIT(23), - XSI_USB_VIP_PORT_MASK = BIT(25), -@@ -629,6 +635,11 @@ static inline bool airoha_is_7581(struct - return eth->soc->version == 0x7581; - } - -+static inline bool airoha_is_7583(struct airoha_eth *eth) -+{ -+ return eth->soc->version == 0x7583; -+} -+ - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -37,6 +37,9 @@ static int airoha_ppe_get_num_stats_entr - if (!IS_ENABLED(CONFIG_NET_AIROHA_FLOW_STATS)) - return -EOPNOTSUPP; - -+ if (airoha_is_7583(ppe->eth)) -+ return -EOPNOTSUPP; -+ - return PPE_STATS_NUM_ENTRIES; - } - diff --git a/target/linux/airoha/patches-6.12/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch b/target/linux/airoha/patches-6.12/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch deleted file mode 100644 index 7e86417f9de..00000000000 --- a/target/linux/airoha/patches-6.12/100-v6.17-net-airoha-npu-Add-missing-MODULE_FIRMWARE-macros.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4e7e471e2e3f9085fe1dbe821c4dd904a917c66a Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 1 Aug 2025 09:12:25 +0200 -Subject: [PATCH] net: airoha: npu: Add missing MODULE_FIRMWARE macros - -Introduce missing MODULE_FIRMWARE definitions for firmware autoload. - -Fixes: 23290c7bc190d ("net: airoha: Introduce Airoha NPU support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250801-airoha-npu-missing-module-firmware-v2-1-e860c824d515@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -741,6 +741,8 @@ static struct platform_driver airoha_npu - }; - module_platform_driver(airoha_npu_driver); - -+MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); -+MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Lorenzo Bianconi "); - MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); diff --git a/target/linux/airoha/patches-6.12/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch b/target/linux/airoha/patches-6.12/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch deleted file mode 100644 index 71453fd57fd..00000000000 --- a/target/linux/airoha/patches-6.12/101-v6.17-net-airoha-Fix-a-NULL-vs-IS_ERR-bug-in-airoha_npu_ru.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1e5e40f2558c07f6bc60a8983000309cc0a9d600 Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Tue, 15 Jul 2025 18:01:10 -0500 -Subject: [PATCH] net: airoha: Fix a NULL vs IS_ERR() bug in - airoha_npu_run_firmware() - -The devm_ioremap_resource() function returns error pointers. It never -returns NULL. Update the check to match. - -Fixes: e27dba1951ce ("net: Use of_reserved_mem_region_to_resource{_byname}() for "memory-region"") -Signed-off-by: Dan Carpenter -Acked-by: Lorenzo Bianconi -Link: https://patch.msgid.link/fc6d194e-6bf5-49ca-bc77-3fdfda62c434@sabinyo.mountain -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -201,8 +201,8 @@ static int airoha_npu_run_firmware(struc - } - - addr = devm_ioremap(dev, rmem->base, rmem->size); -- if (!addr) { -- ret = -ENOMEM; -+ if (IS_ERR(addr)) { -+ ret = PTR_ERR(addr); - goto out; - } - diff --git a/target/linux/airoha/patches-6.12/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch b/target/linux/airoha/patches-6.12/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch deleted file mode 100644 index 09972a9b629..00000000000 --- a/target/linux/airoha/patches-6.12/102-02-v6.19-net-airoha-npu-Add-airoha_npu_soc_data-struct.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0850ae496d534847ec2c26744521c1bce04ec59d Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 13 Oct 2025 15:58:50 +0200 -Subject: [PATCH 2/3] net: airoha: npu: Add airoha_npu_soc_data struct - -Introduce airoha_npu_soc_data structure in order to generalize per-SoC -NPU firmware info. Introduce airoha_npu_load_firmware utility routine. -This is a preliminary patch in order to introduce AN7583 NPU support. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20251013-airoha-npu-7583-v3-2-00f748b5a0c7@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 77 ++++++++++++++++-------- - 1 file changed, 51 insertions(+), 26 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -103,6 +103,16 @@ enum { - QDMA_WAN_PON_XDSL, - }; - -+struct airoha_npu_fw { -+ const char *name; -+ int max_size; -+}; -+ -+struct airoha_npu_soc_data { -+ struct airoha_npu_fw fw_rv32; -+ struct airoha_npu_fw fw_data; -+}; -+ - #define MBOX_MSG_FUNC_ID GENMASK(14, 11) - #define MBOX_MSG_STATIC_BUF BIT(5) - #define MBOX_MSG_STATUS GENMASK(4, 2) -@@ -182,49 +192,53 @@ static int airoha_npu_send_msg(struct ai - return ret; - } - --static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, -- struct reserved_mem *rmem) -+static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, -+ const struct airoha_npu_fw *fw_info) - { - const struct firmware *fw; -- void __iomem *addr; - int ret; - -- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_RV32, dev); -+ ret = request_firmware(&fw, fw_info->name, dev); - if (ret) - return ret == -ENOENT ? -EPROBE_DEFER : ret; - -- if (fw->size > NPU_EN7581_FIRMWARE_RV32_MAX_SIZE) { -+ if (fw->size > fw_info->max_size) { - dev_err(dev, "%s: fw size too overlimit (%zu)\n", -- NPU_EN7581_FIRMWARE_RV32, fw->size); -+ fw_info->name, fw->size); - ret = -E2BIG; - goto out; - } - -- addr = devm_ioremap(dev, rmem->base, rmem->size); -- if (IS_ERR(addr)) { -- ret = PTR_ERR(addr); -- goto out; -- } -- - memcpy_toio(addr, fw->data, fw->size); -+out: - release_firmware(fw); - -- ret = request_firmware(&fw, NPU_EN7581_FIRMWARE_DATA, dev); -- if (ret) -- return ret == -ENOENT ? -EPROBE_DEFER : ret; -+ return ret; -+} - -- if (fw->size > NPU_EN7581_FIRMWARE_DATA_MAX_SIZE) { -- dev_err(dev, "%s: fw size too overlimit (%zu)\n", -- NPU_EN7581_FIRMWARE_DATA, fw->size); -- ret = -E2BIG; -- goto out; -- } -+static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, -+ struct reserved_mem *rmem) -+{ -+ const struct airoha_npu_soc_data *soc; -+ void __iomem *addr; -+ int ret; - -- memcpy_toio(base + REG_NPU_LOCAL_SRAM, fw->data, fw->size); --out: -- release_firmware(fw); -+ soc = of_device_get_match_data(dev); -+ if (!soc) -+ return -EINVAL; - -- return ret; -+ addr = devm_ioremap(dev, rmem->base, rmem->size); -+ if (IS_ERR(addr)) -+ return PTR_ERR(addr); -+ -+ /* Load rv32 npu firmware */ -+ ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32); -+ if (ret) -+ return ret; -+ -+ /* Load data npu firmware */ -+ return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, -+ &soc->fw_data); - } - - static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) -@@ -596,8 +610,19 @@ void airoha_npu_put(struct airoha_npu *n - } - EXPORT_SYMBOL_GPL(airoha_npu_put); - -+static const struct airoha_npu_soc_data en7581_npu_soc_data = { -+ .fw_rv32 = { -+ .name = NPU_EN7581_FIRMWARE_RV32, -+ .max_size = NPU_EN7581_FIRMWARE_RV32_MAX_SIZE, -+ }, -+ .fw_data = { -+ .name = NPU_EN7581_FIRMWARE_DATA, -+ .max_size = NPU_EN7581_FIRMWARE_DATA_MAX_SIZE, -+ }, -+}; -+ - static const struct of_device_id of_airoha_npu_match[] = { -- { .compatible = "airoha,en7581-npu" }, -+ { .compatible = "airoha,en7581-npu", .data = &en7581_npu_soc_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, of_airoha_npu_match); diff --git a/target/linux/airoha/patches-6.12/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch b/target/linux/airoha/patches-6.12/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch deleted file mode 100644 index a628d09b779..00000000000 --- a/target/linux/airoha/patches-6.12/102-03-v6.19-net-airoha-npu-Add-7583-SoC-support.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 4478596f71d92060c9093bdf1d2d940881f41bcc Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 13 Oct 2025 15:58:51 +0200 -Subject: [PATCH 3/3] net: airoha: npu: Add 7583 SoC support - -Introduce support for Airoha 7583 SoC NPU selecting proper firmware images. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20251013-airoha-npu-7583-v3-3-00f748b5a0c7@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -16,6 +16,8 @@ - - #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" - #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" -+#define NPU_AN7583_FIRMWARE_DATA "airoha/an7583_npu_data.bin" -+#define NPU_AN7583_FIRMWARE_RV32 "airoha/an7583_npu_rv32.bin" - #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 - #define NPU_EN7581_FIRMWARE_DATA_MAX_SIZE 0x10000 - #define NPU_DUMP_SIZE 512 -@@ -621,8 +623,20 @@ static const struct airoha_npu_soc_data - }, - }; - -+static const struct airoha_npu_soc_data an7583_npu_soc_data = { -+ .fw_rv32 = { -+ .name = NPU_AN7583_FIRMWARE_RV32, -+ .max_size = NPU_EN7581_FIRMWARE_RV32_MAX_SIZE, -+ }, -+ .fw_data = { -+ .name = NPU_AN7583_FIRMWARE_DATA, -+ .max_size = NPU_EN7581_FIRMWARE_DATA_MAX_SIZE, -+ }, -+}; -+ - static const struct of_device_id of_airoha_npu_match[] = { - { .compatible = "airoha,en7581-npu", .data = &en7581_npu_soc_data }, -+ { .compatible = "airoha,an7583-npu", .data = &an7583_npu_soc_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, of_airoha_npu_match); -@@ -768,6 +782,8 @@ module_platform_driver(airoha_npu_driver - - MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); - MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); -+MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_DATA); -+MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_RV32); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Lorenzo Bianconi "); - MODULE_DESCRIPTION("Airoha Network Processor Unit driver"); diff --git a/target/linux/airoha/patches-6.12/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch b/target/linux/airoha/patches-6.12/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch deleted file mode 100644 index 036144280f5..00000000000 --- a/target/linux/airoha/patches-6.12/103-v6.19-net-airoha-Remove-code-duplication-in-airoha_regs.h.patch +++ /dev/null @@ -1,342 +0,0 @@ -From 99ad2b6815f41acbec15ab051ccc79b11b05710a Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 22 Oct 2025 09:11:12 +0200 -Subject: [PATCH] net: airoha: Remove code duplication in airoha_regs.h - -This patch does not introduce any logical change, it just removes -duplicated code in airoha_regs.h. -Fix naming conventions in airoha_regs.h. - -Reviewed-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251022-airoha-regs-cosmetics-v2-1-e0425b3f2c2c@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 102 ++++++++++---------- - drivers/net/ethernet/airoha/airoha_regs.h | 109 ++++++++++------------ - 2 files changed, 100 insertions(+), 111 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -137,11 +137,11 @@ static void airoha_fe_maccr_init(struct - - for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) - airoha_fe_set(eth, REG_GDM_FWD_CFG(p), -- GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | -- GDM_DROP_CRC_ERR); -+ GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK | -+ GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK); - -- airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, -- FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); -+ airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK, -+ FIELD_PREP(CDM_VLAN_MASK, 0x8100)); - - airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); - } -@@ -403,46 +403,46 @@ static int airoha_fe_mc_vlan_clear(struc - static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) - { - /* CDM1_CRSN_QSEL */ -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_22 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_22 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_22), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_22), - CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_08 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_08 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_08), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_08), - CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_21 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_21 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_21), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_21), - CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_24 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_24 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_24), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_24), - CDM_CRSN_QSEL_Q6)); -- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_25 >> 2), -- CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), -- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_25 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_25), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_25), - CDM_CRSN_QSEL_Q1)); - /* CDM2_CRSN_QSEL */ -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_08 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_08 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_08), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_08), - CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_21 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_21 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_21), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_21), - CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_22 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_22 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_22), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_22), - CDM_CRSN_QSEL_Q1)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_24 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_24 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_24), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_24), - CDM_CRSN_QSEL_Q6)); -- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_25 >> 2), -- CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), -- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), -+ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_25 >> 2), -+ CDM_CRSN_QSEL_REASON_MASK(CRSN_25), -+ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_25), - CDM_CRSN_QSEL_Q1)); - } - -@@ -462,18 +462,18 @@ static int airoha_fe_init(struct airoha_ - airoha_fe_wr(eth, REG_FE_PCE_CFG, - PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); - /* set vip queue selection to ring 1 */ -- airoha_fe_rmw(eth, REG_CDM1_FWD_CFG, CDM1_VIP_QSEL_MASK, -- FIELD_PREP(CDM1_VIP_QSEL_MASK, 0x4)); -- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_VIP_QSEL_MASK, -- FIELD_PREP(CDM2_VIP_QSEL_MASK, 0x4)); -+ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK, -+ FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4)); -+ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_VIP_QSEL_MASK, -+ FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4)); - /* set GDM4 source interface offset to 8 */ -- airoha_fe_rmw(eth, REG_GDM4_SRC_PORT_SET, -- GDM4_SPORT_OFF2_MASK | -- GDM4_SPORT_OFF1_MASK | -- GDM4_SPORT_OFF0_MASK, -- FIELD_PREP(GDM4_SPORT_OFF2_MASK, 8) | -- FIELD_PREP(GDM4_SPORT_OFF1_MASK, 8) | -- FIELD_PREP(GDM4_SPORT_OFF0_MASK, 8)); -+ airoha_fe_rmw(eth, REG_GDM_SRC_PORT_SET(4), -+ GDM_SPORT_OFF2_MASK | -+ GDM_SPORT_OFF1_MASK | -+ GDM_SPORT_OFF0_MASK, -+ FIELD_PREP(GDM_SPORT_OFF2_MASK, 8) | -+ FIELD_PREP(GDM_SPORT_OFF1_MASK, 8) | -+ FIELD_PREP(GDM_SPORT_OFF0_MASK, 8)); - - /* set PSE Page as 128B */ - airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, -@@ -499,8 +499,8 @@ static int airoha_fe_init(struct airoha_ - airoha_fe_set(eth, REG_GDM_MISC_CFG, - GDM2_RDM_ACK_WAIT_PREF_MASK | - GDM2_CHN_VLD_MODE_MASK); -- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, -- FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); -+ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_OAM_QSEL_MASK, -+ FIELD_PREP(CDM_OAM_QSEL_MASK, 15)); - - /* init fragment and assemble Force Port */ - /* NPU Core-3, NPU Bridge Channel-3 */ -@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_ - FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | - FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); - -- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); -- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); - - airoha_fe_crsn_qsel_init(eth); - -@@ -523,7 +523,7 @@ static int airoha_fe_init(struct airoha_ - airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); - - /* default aging mode for mbi unlock issue */ -- airoha_fe_rmw(eth, REG_GDM2_CHN_RLS, -+ airoha_fe_rmw(eth, REG_GDM_CHN_RLS(2), - MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, - FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | - FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); -@@ -1718,7 +1718,7 @@ static int airhoha_set_gdm2_loopback(str - pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 - : FE_PSE_PORT_GDM4; - airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); -- airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); -+ airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC_MASK); - - /* Enable GDM2 loopback */ - airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -23,6 +23,8 @@ - #define GDM3_BASE 0x1100 - #define GDM4_BASE 0x2500 - -+#define CDM_BASE(_n) \ -+ ((_n) == 2 ? CDM2_BASE : CDM1_BASE) - #define GDM_BASE(_n) \ - ((_n) == 4 ? GDM4_BASE : \ - (_n) == 3 ? GDM3_BASE : \ -@@ -109,30 +111,24 @@ - #define PATN_DP_MASK GENMASK(31, 16) - #define PATN_SP_MASK GENMASK(15, 0) - --#define REG_CDM1_VLAN_CTRL CDM1_BASE --#define CDM1_VLAN_MASK GENMASK(31, 16) -+#define REG_CDM_VLAN_CTRL(_n) CDM_BASE(_n) -+#define CDM_VLAN_MASK GENMASK(31, 16) - --#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) --#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) -+#define REG_CDM_FWD_CFG(_n) (CDM_BASE(_n) + 0x08) -+#define CDM_OAM_QSEL_MASK GENMASK(31, 27) -+#define CDM_VIP_QSEL_MASK GENMASK(24, 20) - --#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) --#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ -- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) -- --#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) --#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) --#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) -- --#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) --#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ -+#define REG_CDM_CRSN_QSEL(_n, _m) (CDM_BASE(_n) + 0x10 + ((_m) << 2)) -+#define CDM_CRSN_QSEL_REASON_MASK(_n) \ - GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) - - #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) --#define GDM_DROP_CRC_ERR BIT(23) --#define GDM_IP4_CKSUM BIT(22) --#define GDM_TCP_CKSUM BIT(21) --#define GDM_UDP_CKSUM BIT(20) --#define GDM_STRIP_CRC BIT(16) -+#define GDM_PAD_EN_MASK BIT(28) -+#define GDM_DROP_CRC_ERR_MASK BIT(23) -+#define GDM_IP4_CKSUM_MASK BIT(22) -+#define GDM_TCP_CKSUM_MASK BIT(21) -+#define GDM_UDP_CKSUM_MASK BIT(20) -+#define GDM_STRIP_CRC_MASK BIT(16) - #define GDM_UCFQ_MASK GENMASK(15, 12) - #define GDM_BCFQ_MASK GENMASK(11, 8) - #define GDM_MCFQ_MASK GENMASK(7, 4) -@@ -156,6 +152,10 @@ - #define LBK_CHAN_MODE_MASK BIT(1) - #define LPBK_EN_MASK BIT(0) - -+#define REG_GDM_CHN_RLS(_n) (GDM_BASE(_n) + 0x20) -+#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) -+#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) -+ - #define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) - #define REG_GDM_RXCHN_EN(_n) (GDM_BASE(_n) + 0x28) - -@@ -168,10 +168,10 @@ - #define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) - #define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) - --#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) -+#define REG_FE_GDM_MIB_CFG(_n) (GDM_BASE(_n) + 0xf4) - #define FE_STRICT_RFC2819_MODE_MASK BIT(31) --#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) --#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) -+#define FE_GDM_TX_MIB_SPLIT_EN_MASK BIT(17) -+#define FE_GDM_RX_MIB_SPLIT_EN_MASK BIT(16) - #define FE_TX_MIB_ID_MASK GENMASK(15, 8) - #define FE_RX_MIB_ID_MASK GENMASK(7, 0) - -@@ -214,6 +214,33 @@ - #define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) - #define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) - -+#define REG_GDM_SRC_PORT_SET(_n) (GDM_BASE(_n) + 0x23c) -+#define GDM_SPORT_OFF2_MASK GENMASK(19, 16) -+#define GDM_SPORT_OFF1_MASK GENMASK(15, 12) -+#define GDM_SPORT_OFF0_MASK GENMASK(11, 8) -+ -+#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) -+#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) -+#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) -+#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) -+ -+#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) -+#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) -+#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) -+#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) -+#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) -+#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) -+#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) -+#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) -+#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) -+#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) -+#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) -+#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) -+#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) -+#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) -+#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) -+#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) -+ - #define REG_PPE_GLO_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x200) - #define PPE_GLO_CFG_BUSY_MASK BIT(31) - #define PPE_GLO_CFG_FLOW_DROP_UPDATE_MASK BIT(9) -@@ -326,44 +353,6 @@ - - #define REG_UPDMEM_DATA(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x374) - --#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) --#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) --#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) --#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) -- --#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) --#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) --#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) --#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) --#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) --#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) --#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) --#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) --#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) --#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) --#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) --#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) --#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) --#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) --#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) --#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) -- --#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) --#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) --#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) -- --#define REG_GDM3_FWD_CFG GDM3_BASE --#define GDM3_PAD_EN_MASK BIT(28) -- --#define REG_GDM4_FWD_CFG GDM4_BASE --#define GDM4_PAD_EN_MASK BIT(28) --#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) -- --#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) --#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) --#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) --#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) -- - #define REG_IP_FRAG_FP 0x2010 - #define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) - #define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) diff --git a/target/linux/airoha/patches-6.12/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch b/target/linux/airoha/patches-6.12/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch deleted file mode 100644 index f1172323010..00000000000 --- a/target/linux/airoha/patches-6.12/104-v6.16-net-airoha-Fix-an-error-handling-path-in-airoha_prob.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 3ef07434c7dbfba302df477bb6c70e082965f232 Mon Sep 17 00:00:00 2001 -From: Christophe JAILLET -Date: Sat, 5 Jul 2025 10:34:32 +0200 -Subject: [PATCH] net: airoha: Fix an error handling path in airoha_probe() - -If an error occurs after a successful airoha_hw_init() call, -airoha_ppe_deinit() needs to be called as already done in the remove -function. - -Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") -Signed-off-by: Christophe JAILLET -Reviewed-by: Simon Horman -Acked-by: Lorenzo Bianconi -Link: https://patch.msgid.link/1c940851b4fa3c3ed2a142910c821493a136f121.1746715755.git.christophe.jaillet@wanadoo.fr -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3065,6 +3065,7 @@ static int airoha_probe(struct platform_ - error_napi_stop: - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) - airoha_qdma_stop_napi(ð->qdma[i]); -+ airoha_ppe_deinit(eth); - error_hw_cleanup: - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) - airoha_hw_cleanup(ð->qdma[i]); diff --git a/target/linux/airoha/patches-6.12/104-v6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch b/target/linux/airoha/patches-6.12/104-v6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch deleted file mode 100644 index f27cd14cdaf..00000000000 --- a/target/linux/airoha/patches-6.12/104-v6.19-net-airoha-Fix-a-copy-and-paste-bug-in-probe.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 05e090620bacf317020f9591cfff8926093380bd Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Fri, 24 Oct 2025 14:23:35 +0300 -Subject: [PATCH] net: airoha: Fix a copy and paste bug in probe() - -This code has a copy and paste bug where it accidentally checks "if (err)" -instead of checking if "xsi_rsts" is NULL. Also, as a free bonus, I -changed the allocation from kzalloc() to kcalloc() which is a kernel -hardening measure to protect against integer overflows. - -Fixes: 5863b4e065e2 ("net: airoha: Add airoha_eth_soc_data struct") -Signed-off-by: Dan Carpenter -Acked-by: Lorenzo Bianconi -Link: https://patch.msgid.link/aPtht6y5DRokn9zv@stanley.mountain -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3011,11 +3011,11 @@ static int airoha_probe(struct platform_ - return err; - } - -- xsi_rsts = devm_kzalloc(eth->dev, -- eth->soc->num_xsi_rsts * sizeof(*xsi_rsts), -+ xsi_rsts = devm_kcalloc(eth->dev, -+ eth->soc->num_xsi_rsts, sizeof(*xsi_rsts), - GFP_KERNEL); -- if (err) -- return err; -+ if (!xsi_rsts) -+ return -ENOMEM; - - eth->xsi_rsts = xsi_rsts; - for (i = 0; i < eth->soc->num_xsi_rsts; i++) diff --git a/target/linux/airoha/patches-6.12/105-v6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch b/target/linux/airoha/patches-6.12/105-v6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch deleted file mode 100644 index 0c690b0d655..00000000000 --- a/target/linux/airoha/patches-6.12/105-v6.17-net-airoha-Get-rid-of-dma_sync_single_for_device-in-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4cd9d227ab838b3590c4b27e3707b8c3ef14d7e9 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 25 Jun 2025 16:43:15 +0200 -Subject: [PATCH] net: airoha: Get rid of dma_sync_single_for_device() in - airoha_qdma_fill_rx_queue() - -Since the page_pool for airoha_eth driver is created with -PP_FLAG_DMA_SYNC_DEV flag, we do not need to sync_for_device each page -received from the pool since it is already done by the page_pool codebase. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Alexander Lobakin -Link: https://patch.msgid.link/20250625-airoha-sync-for-device-v1-1-923741deaabf@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -539,9 +539,7 @@ static int airoha_fe_init(struct airoha_ - - static int airoha_qdma_fill_rx_queue(struct airoha_queue *q) - { -- enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); - struct airoha_qdma *qdma = q->qdma; -- struct airoha_eth *eth = qdma->eth; - int qid = q - &qdma->q_rx[0]; - int nframes = 0; - -@@ -565,9 +563,6 @@ static int airoha_qdma_fill_rx_queue(str - e->dma_addr = page_pool_get_dma_addr(page) + offset; - e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); - -- dma_sync_single_for_device(eth->dev, e->dma_addr, e->dma_len, -- dir); -- - val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); - WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); - WRITE_ONCE(desc->addr, cpu_to_le32(e->dma_addr)); diff --git a/target/linux/airoha/patches-6.12/106-v6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch b/target/linux/airoha/patches-6.12/106-v6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch deleted file mode 100644 index 251395c751e..00000000000 --- a/target/linux/airoha/patches-6.12/106-v6.16-net-airoha-fix-potential-use-after-free-in-airoha_np.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 3cd582e7d0787506990ef0180405eb6224fa90a6 Mon Sep 17 00:00:00 2001 -From: Alok Tiwari -Date: Tue, 15 Jul 2025 07:30:58 -0700 -Subject: [PATCH] net: airoha: fix potential use-after-free in airoha_npu_get() - -np->name was being used after calling of_node_put(np), which -releases the node and can lead to a use-after-free bug. -Previously, of_node_put(np) was called unconditionally after -of_find_device_by_node(np), which could result in a use-after-free if -pdev is NULL. - -This patch moves of_node_put(np) after the error check to ensure -the node is only released after both the error and success cases -are handled appropriately, preventing potential resource issues. - -Fixes: 23290c7bc190 ("net: airoha: Introduce Airoha NPU support") -Signed-off-by: Alok Tiwari -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250715143102.3458286-1-alok.a.tiwari@oracle.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -567,12 +567,13 @@ struct airoha_npu *airoha_npu_get(struct - return ERR_PTR(-ENODEV); - - pdev = of_find_device_by_node(np); -- of_node_put(np); - - if (!pdev) { - dev_err(dev, "cannot find device node %s\n", np->name); -+ of_node_put(np); - return ERR_PTR(-ENODEV); - } -+ of_node_put(np); - - if (!try_module_get(THIS_MODULE)) { - dev_err(dev, "failed to get the device driver module\n"); diff --git a/target/linux/airoha/patches-6.12/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch b/target/linux/airoha/patches-6.12/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch deleted file mode 100644 index 0848cb410e6..00000000000 --- a/target/linux/airoha/patches-6.12/107-v6.19-pwm-airoha-Add-support-for-EN7581-SoC.patch +++ /dev/null @@ -1,689 +0,0 @@ -From 61d7c2f94d391594de08d8a52a7c2630d2f3d263 Mon Sep 17 00:00:00 2001 -From: Benjamin Larsson -Date: Mon, 13 Oct 2025 12:34:03 +0200 -Subject: [PATCH] pwm: airoha: Add support for EN7581 SoC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce driver for PWM module available on EN7581 SoC. - -Limitations: -- Only 8 concurrent waveform generators are available for 8 combinations of - duty_cycle and period. Waveform generators are shared between 16 GPIO - pins and 17 SIPO GPIO pins. -- Supports only normal polarity. -- On configuration the currently running period is completed. -- Minimum supported period is 4 ms -- Maximum supported period is 1s - -Signed-off-by: Benjamin Larsson -Reviewed-by: AngeloGioacchino Del Regno -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Andy Shevchenko -Co-developed-by: Christian Marangi -Signed-off-by: Christian Marangi -Link: https://patch.msgid.link/20251013103408.14724-1-ansuelsmth@gmail.com -Signed-off-by: Uwe Kleine-König ---- - drivers/pwm/Kconfig | 10 + - drivers/pwm/Makefile | 1 + - drivers/pwm/pwm-airoha.c | 622 +++++++++++++++++++++++++++++++++++++++ - 3 files changed, 633 insertions(+) - create mode 100644 drivers/pwm/pwm-airoha.c - ---- a/drivers/pwm/Kconfig -+++ b/drivers/pwm/Kconfig -@@ -54,6 +54,16 @@ config PWM_ADP5585 - This option enables support for the PWM function found in the Analog - Devices ADP5585. - -+config PWM_AIROHA -+ tristate "Airoha PWM support" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ select REGMAP_MMIO -+ help -+ Generic PWM framework driver for Airoha SoC. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called pwm-airoha. -+ - config PWM_APPLE - tristate "Apple SoC PWM support" - depends on ARCH_APPLE || COMPILE_TEST ---- a/drivers/pwm/Makefile -+++ b/drivers/pwm/Makefile -@@ -2,6 +2,7 @@ - obj-$(CONFIG_PWM) += core.o - obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o - obj-$(CONFIG_PWM_ADP5585) += pwm-adp5585.o -+obj-$(CONFIG_PWM_AIROHA) += pwm-airoha.o - obj-$(CONFIG_PWM_APPLE) += pwm-apple.o - obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o - obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o ---- /dev/null -+++ b/drivers/pwm/pwm-airoha.c -@@ -0,0 +1,622 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright 2022 Markus Gothe -+ * Copyright 2025 Christian Marangi -+ * -+ * Limitations: -+ * - Only 8 concurrent waveform generators are available for 8 combinations of -+ * duty_cycle and period. Waveform generators are shared between 16 GPIO -+ * pins and 17 SIPO GPIO pins. -+ * - Supports only normal polarity. -+ * - On configuration the currently running period is completed. -+ * - Minimum supported period is 4 ms -+ * - Maximum supported period is 1s -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define AIROHA_PWM_REG_SGPIO_LED_DATA 0x0024 -+#define AIROHA_PWM_SGPIO_LED_DATA_SHIFT_FLAG BIT(31) -+#define AIROHA_PWM_SGPIO_LED_DATA_DATA GENMASK(16, 0) -+ -+#define AIROHA_PWM_REG_SGPIO_CLK_DIVR 0x0028 -+#define AIROHA_PWM_SGPIO_CLK_DIVR GENMASK(1, 0) -+#define AIROHA_PWM_SGPIO_CLK_DIVR_32 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 3) -+#define AIROHA_PWM_SGPIO_CLK_DIVR_16 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 2) -+#define AIROHA_PWM_SGPIO_CLK_DIVR_8 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 1) -+#define AIROHA_PWM_SGPIO_CLK_DIVR_4 FIELD_PREP_CONST(AIROHA_PWM_SGPIO_CLK_DIVR, 0) -+ -+#define AIROHA_PWM_REG_SGPIO_CLK_DLY 0x002c -+ -+#define AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG 0x0030 -+#define AIROHA_PWM_SERIAL_GPIO_FLASH_MODE BIT(1) -+#define AIROHA_PWM_SERIAL_GPIO_MODE_74HC164 BIT(0) -+ -+#define AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(_n) (0x003c + (4 * (_n))) -+#define AIROHA_PWM_REG_GPIO_FLASH_PRD_SHIFT(_n) (16 * (_n)) -+#define AIROHA_PWM_GPIO_FLASH_PRD_LOW GENMASK(15, 8) -+#define AIROHA_PWM_GPIO_FLASH_PRD_HIGH GENMASK(7, 0) -+ -+#define AIROHA_PWM_REG_GPIO_FLASH_MAP(_n) (0x004c + (4 * (_n))) -+#define AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(_n) (4 * (_n)) -+#define AIROHA_PWM_GPIO_FLASH_EN BIT(3) -+#define AIROHA_PWM_GPIO_FLASH_SET_ID GENMASK(2, 0) -+ -+/* Register map is equal to GPIO flash map */ -+#define AIROHA_PWM_REG_SIPO_FLASH_MAP(_n) (0x0054 + (4 * (_n))) -+ -+#define AIROHA_PWM_REG_CYCLE_CFG_VALUE(_n) (0x0098 + (4 * (_n))) -+#define AIROHA_PWM_REG_CYCLE_CFG_SHIFT(_n) (8 * (_n)) -+#define AIROHA_PWM_WAVE_GEN_CYCLE GENMASK(7, 0) -+ -+/* GPIO/SIPO flash map handles 8 pins in one register */ -+#define AIROHA_PWM_PINS_PER_FLASH_MAP 8 -+/* Cycle(Period) registers handles 4 generators in one 32-bit register */ -+#define AIROHA_PWM_BUCKET_PER_CYCLE_CFG 4 -+/* Flash(Duty) producer handles 2 generators in one 32-bit register */ -+#define AIROHA_PWM_BUCKET_PER_FLASH_PROD 2 -+ -+#define AIROHA_PWM_NUM_BUCKETS 8 -+/* -+ * The first 16 GPIO pins, GPIO0-GPIO15, are mapped into 16 PWM channels, 0-15. -+ * The SIPO GPIO pins are 17 pins which are mapped into 17 PWM channels, 16-32. -+ * However, we've only got 8 concurrent waveform generators and can therefore -+ * only use up to 8 different combinations of duty cycle and period at a time. -+ */ -+#define AIROHA_PWM_NUM_GPIO 16 -+#define AIROHA_PWM_NUM_SIPO 17 -+#define AIROHA_PWM_MAX_CHANNELS (AIROHA_PWM_NUM_GPIO + AIROHA_PWM_NUM_SIPO) -+ -+struct airoha_pwm_bucket { -+ /* Concurrent access protected by PWM core */ -+ int used; -+ u32 period_ticks; -+ u32 duty_ticks; -+}; -+ -+struct airoha_pwm { -+ struct regmap *regmap; -+ -+ DECLARE_BITMAP(initialized, AIROHA_PWM_MAX_CHANNELS); -+ -+ struct airoha_pwm_bucket buckets[AIROHA_PWM_NUM_BUCKETS]; -+ -+ /* Cache bucket used by each pwm channel */ -+ u8 channel_bucket[AIROHA_PWM_MAX_CHANNELS]; -+}; -+ -+/* The PWM hardware supports periods between 4 ms and 1 s */ -+#define AIROHA_PWM_PERIOD_TICK_NS (4 * NSEC_PER_MSEC) -+#define AIROHA_PWM_PERIOD_MAX_NS (1 * NSEC_PER_SEC) -+/* It is represented internally as 1/250 s between 1 and 250. Unit is ticks. */ -+#define AIROHA_PWM_PERIOD_MIN 1 -+#define AIROHA_PWM_PERIOD_MAX 250 -+/* Duty cycle is relative with 255 corresponding to 100% */ -+#define AIROHA_PWM_DUTY_FULL 255 -+ -+static void airoha_pwm_get_flash_map_addr_and_shift(unsigned int hwpwm, -+ u32 *addr, u32 *shift) -+{ -+ unsigned int offset, hwpwm_bit; -+ -+ if (hwpwm >= AIROHA_PWM_NUM_GPIO) { -+ unsigned int sipohwpwm = hwpwm - AIROHA_PWM_NUM_GPIO; -+ -+ offset = sipohwpwm / AIROHA_PWM_PINS_PER_FLASH_MAP; -+ hwpwm_bit = sipohwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP; -+ -+ /* One FLASH_MAP register handles 8 pins */ -+ *shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(hwpwm_bit); -+ *addr = AIROHA_PWM_REG_SIPO_FLASH_MAP(offset); -+ } else { -+ offset = hwpwm / AIROHA_PWM_PINS_PER_FLASH_MAP; -+ hwpwm_bit = hwpwm % AIROHA_PWM_PINS_PER_FLASH_MAP; -+ -+ /* One FLASH_MAP register handles 8 pins */ -+ *shift = AIROHA_PWM_REG_GPIO_FLASH_MAP_SHIFT(hwpwm_bit); -+ *addr = AIROHA_PWM_REG_GPIO_FLASH_MAP(offset); -+ } -+} -+ -+static u32 airoha_pwm_get_period_ticks_from_ns(u32 period_ns) -+{ -+ return period_ns / AIROHA_PWM_PERIOD_TICK_NS; -+} -+ -+static u32 airoha_pwm_get_duty_ticks_from_ns(u32 period_ns, u32 duty_ns) -+{ -+ return mul_u64_u32_div(duty_ns, AIROHA_PWM_DUTY_FULL, period_ns); -+} -+ -+static u32 airoha_pwm_get_period_ns_from_ticks(u32 period_tick) -+{ -+ return period_tick * AIROHA_PWM_PERIOD_TICK_NS; -+} -+ -+static u32 airoha_pwm_get_duty_ns_from_ticks(u32 period_tick, u32 duty_tick) -+{ -+ u32 period_ns = period_tick * AIROHA_PWM_PERIOD_TICK_NS; -+ -+ /* -+ * Overflow can't occur in multiplication as duty_tick is just 8 bit -+ * and period_ns is clamped to AIROHA_PWM_PERIOD_MAX_NS and fit in a -+ * u64. -+ */ -+ return DIV_U64_ROUND_UP(duty_tick * period_ns, AIROHA_PWM_DUTY_FULL); -+} -+ -+static int airoha_pwm_get_bucket(struct airoha_pwm *pc, int bucket, -+ u64 *period_ns, u64 *duty_ns) -+{ -+ struct regmap *map = pc->regmap; -+ u32 period_tick, duty_tick; -+ unsigned int offset; -+ u32 shift, val; -+ int ret; -+ -+ offset = bucket / AIROHA_PWM_BUCKET_PER_CYCLE_CFG; -+ shift = bucket % AIROHA_PWM_BUCKET_PER_CYCLE_CFG; -+ shift = AIROHA_PWM_REG_CYCLE_CFG_SHIFT(shift); -+ -+ ret = regmap_read(map, AIROHA_PWM_REG_CYCLE_CFG_VALUE(offset), &val); -+ if (ret) -+ return ret; -+ -+ period_tick = FIELD_GET(AIROHA_PWM_WAVE_GEN_CYCLE, val >> shift); -+ *period_ns = airoha_pwm_get_period_ns_from_ticks(period_tick); -+ -+ offset = bucket / AIROHA_PWM_BUCKET_PER_FLASH_PROD; -+ shift = bucket % AIROHA_PWM_BUCKET_PER_FLASH_PROD; -+ shift = AIROHA_PWM_REG_GPIO_FLASH_PRD_SHIFT(shift); -+ -+ ret = regmap_read(map, AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(offset), -+ &val); -+ if (ret) -+ return ret; -+ -+ duty_tick = FIELD_GET(AIROHA_PWM_GPIO_FLASH_PRD_HIGH, val >> shift); -+ *duty_ns = airoha_pwm_get_duty_ns_from_ticks(period_tick, duty_tick); -+ -+ return 0; -+} -+ -+static int airoha_pwm_get_generator(struct airoha_pwm *pc, u32 duty_ticks, -+ u32 period_ticks) -+{ -+ int best = -ENOENT, unused = -ENOENT; -+ u32 duty_ns, best_duty_ns = 0; -+ u32 best_period_ticks = 0; -+ unsigned int i; -+ -+ duty_ns = airoha_pwm_get_duty_ns_from_ticks(period_ticks, duty_ticks); -+ -+ for (i = 0; i < ARRAY_SIZE(pc->buckets); i++) { -+ struct airoha_pwm_bucket *bucket = &pc->buckets[i]; -+ u32 bucket_period_ticks = bucket->period_ticks; -+ u32 bucket_duty_ticks = bucket->duty_ticks; -+ -+ /* If found, save an unused bucket to return it later */ -+ if (!bucket->used) { -+ unused = i; -+ continue; -+ } -+ -+ /* We found a matching bucket, exit early */ -+ if (duty_ticks == bucket_duty_ticks && -+ period_ticks == bucket_period_ticks) -+ return i; -+ -+ /* -+ * Unlike duty cycle zero, which can be handled by -+ * disabling PWM, a generator is needed for full duty -+ * cycle but it can be reused regardless of period -+ */ -+ if (duty_ticks == AIROHA_PWM_DUTY_FULL && -+ bucket_duty_ticks == AIROHA_PWM_DUTY_FULL) -+ return i; -+ -+ /* -+ * With an unused bucket available, skip searching for -+ * a bucket to recycle (closer to the requested period/duty) -+ */ -+ if (unused >= 0) -+ continue; -+ -+ /* Ignore bucket with invalid period */ -+ if (bucket_period_ticks > period_ticks) -+ continue; -+ -+ /* -+ * Search for a bucket closer to the requested period -+ * that has the maximal possible period that isn't bigger -+ * than the requested period. For that period pick the maximal -+ * duty cycle that isn't bigger than the requested duty_cycle. -+ */ -+ if (bucket_period_ticks >= best_period_ticks) { -+ u32 bucket_duty_ns = airoha_pwm_get_duty_ns_from_ticks(bucket_period_ticks, -+ bucket_duty_ticks); -+ -+ /* Skip bucket that goes over the requested duty */ -+ if (bucket_duty_ns > duty_ns) -+ continue; -+ -+ if (bucket_duty_ns > best_duty_ns) { -+ best_period_ticks = bucket_period_ticks; -+ best_duty_ns = bucket_duty_ns; -+ best = i; -+ } -+ } -+ } -+ -+ /* Return an unused bucket or the best one found (if ever) */ -+ return unused >= 0 ? unused : best; -+} -+ -+static void airoha_pwm_release_bucket_config(struct airoha_pwm *pc, -+ unsigned int hwpwm) -+{ -+ int bucket; -+ -+ /* Nothing to clear, PWM channel never used */ -+ if (!test_bit(hwpwm, pc->initialized)) -+ return; -+ -+ bucket = pc->channel_bucket[hwpwm]; -+ pc->buckets[bucket].used--; -+} -+ -+static int airoha_pwm_apply_bucket_config(struct airoha_pwm *pc, unsigned int bucket, -+ u32 duty_ticks, u32 period_ticks) -+{ -+ u32 mask, shift, val; -+ u32 offset; -+ int ret; -+ -+ offset = bucket / AIROHA_PWM_BUCKET_PER_CYCLE_CFG; -+ shift = bucket % AIROHA_PWM_BUCKET_PER_CYCLE_CFG; -+ shift = AIROHA_PWM_REG_CYCLE_CFG_SHIFT(shift); -+ -+ /* Configure frequency divisor */ -+ mask = AIROHA_PWM_WAVE_GEN_CYCLE << shift; -+ val = FIELD_PREP(AIROHA_PWM_WAVE_GEN_CYCLE, period_ticks) << shift; -+ ret = regmap_update_bits(pc->regmap, AIROHA_PWM_REG_CYCLE_CFG_VALUE(offset), -+ mask, val); -+ if (ret) -+ return ret; -+ -+ offset = bucket / AIROHA_PWM_BUCKET_PER_FLASH_PROD; -+ shift = bucket % AIROHA_PWM_BUCKET_PER_FLASH_PROD; -+ shift = AIROHA_PWM_REG_GPIO_FLASH_PRD_SHIFT(shift); -+ -+ /* Configure duty cycle */ -+ mask = AIROHA_PWM_GPIO_FLASH_PRD_HIGH << shift; -+ val = FIELD_PREP(AIROHA_PWM_GPIO_FLASH_PRD_HIGH, duty_ticks) << shift; -+ ret = regmap_update_bits(pc->regmap, AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(offset), -+ mask, val); -+ if (ret) -+ return ret; -+ -+ mask = AIROHA_PWM_GPIO_FLASH_PRD_LOW << shift; -+ val = FIELD_PREP(AIROHA_PWM_GPIO_FLASH_PRD_LOW, -+ AIROHA_PWM_DUTY_FULL - duty_ticks) << shift; -+ return regmap_update_bits(pc->regmap, AIROHA_PWM_REG_GPIO_FLASH_PRD_SET(offset), -+ mask, val); -+} -+ -+static int airoha_pwm_consume_generator(struct airoha_pwm *pc, -+ u32 duty_ticks, u32 period_ticks, -+ unsigned int hwpwm) -+{ -+ bool config_bucket = false; -+ int bucket, ret; -+ -+ /* -+ * Search for a bucket that already satisfies duty and period -+ * or an unused one. -+ * If not found, -ENOENT is returned. -+ */ -+ bucket = airoha_pwm_get_generator(pc, duty_ticks, period_ticks); -+ if (bucket < 0) -+ return bucket; -+ -+ /* Release previous used bucket (if any) */ -+ airoha_pwm_release_bucket_config(pc, hwpwm); -+ -+ if (!pc->buckets[bucket].used) -+ config_bucket = true; -+ pc->buckets[bucket].used++; -+ -+ if (config_bucket) { -+ pc->buckets[bucket].period_ticks = period_ticks; -+ pc->buckets[bucket].duty_ticks = duty_ticks; -+ ret = airoha_pwm_apply_bucket_config(pc, bucket, -+ duty_ticks, -+ period_ticks); -+ if (ret) { -+ pc->buckets[bucket].used--; -+ return ret; -+ } -+ } -+ -+ return bucket; -+} -+ -+static int airoha_pwm_sipo_init(struct airoha_pwm *pc) -+{ -+ u32 val; -+ int ret; -+ -+ ret = regmap_clear_bits(pc->regmap, AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG, -+ AIROHA_PWM_SERIAL_GPIO_MODE_74HC164); -+ if (ret) -+ return ret; -+ -+ /* Configure shift register chip clock timings, use 32x divisor */ -+ ret = regmap_write(pc->regmap, AIROHA_PWM_REG_SGPIO_CLK_DIVR, -+ AIROHA_PWM_SGPIO_CLK_DIVR_32); -+ if (ret) -+ return ret; -+ -+ /* -+ * Configure the shift register chip clock delay. This needs -+ * to be configured based on the chip characteristics when the SoC -+ * apply the shift register configuration. -+ * This doesn't affect actual PWM operation and is only specific to -+ * the shift register chip. -+ * -+ * For 74HC164 we set it to 0. -+ * -+ * For reference, the actual delay applied is the internal clock -+ * feed to the SGPIO chip + 1. -+ * -+ * From documentation is specified that clock delay should not be -+ * greater than (AIROHA_PWM_REG_SGPIO_CLK_DIVR / 2) - 1. -+ */ -+ ret = regmap_write(pc->regmap, AIROHA_PWM_REG_SGPIO_CLK_DLY, 0); -+ if (ret) -+ return ret; -+ -+ /* -+ * It is necessary to explicitly shift out all zeros after muxing -+ * to initialize the shift register before enabling PWM -+ * mode because in PWM mode SIPO will not start shifting until -+ * it needs to output a non-zero value (bit 31 of led_data -+ * indicates shifting in progress and it must return to zero -+ * before led_data can be written or PWM mode can be set). -+ */ -+ ret = regmap_read_poll_timeout(pc->regmap, AIROHA_PWM_REG_SGPIO_LED_DATA, val, -+ !(val & AIROHA_PWM_SGPIO_LED_DATA_SHIFT_FLAG), -+ 10, 200 * USEC_PER_MSEC); -+ if (ret) -+ return ret; -+ -+ ret = regmap_clear_bits(pc->regmap, AIROHA_PWM_REG_SGPIO_LED_DATA, -+ AIROHA_PWM_SGPIO_LED_DATA_DATA); -+ if (ret) -+ return ret; -+ ret = regmap_read_poll_timeout(pc->regmap, AIROHA_PWM_REG_SGPIO_LED_DATA, val, -+ !(val & AIROHA_PWM_SGPIO_LED_DATA_SHIFT_FLAG), -+ 10, 200 * USEC_PER_MSEC); -+ if (ret) -+ return ret; -+ -+ /* Set SIPO in PWM mode */ -+ return regmap_set_bits(pc->regmap, AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG, -+ AIROHA_PWM_SERIAL_GPIO_FLASH_MODE); -+} -+ -+static int airoha_pwm_config_flash_map(struct airoha_pwm *pc, -+ unsigned int hwpwm, int index) -+{ -+ unsigned int addr; -+ u32 shift; -+ int ret; -+ -+ airoha_pwm_get_flash_map_addr_and_shift(hwpwm, &addr, &shift); -+ -+ /* negative index means disable PWM channel */ -+ if (index < 0) { -+ /* -+ * If we need to disable the PWM, we just put low the -+ * GPIO. No need to setup buckets. -+ */ -+ return regmap_clear_bits(pc->regmap, addr, -+ AIROHA_PWM_GPIO_FLASH_EN << shift); -+ } -+ -+ ret = regmap_update_bits(pc->regmap, addr, -+ AIROHA_PWM_GPIO_FLASH_SET_ID << shift, -+ FIELD_PREP(AIROHA_PWM_GPIO_FLASH_SET_ID, index) << shift); -+ if (ret) -+ return ret; -+ -+ return regmap_set_bits(pc->regmap, addr, AIROHA_PWM_GPIO_FLASH_EN << shift); -+} -+ -+static int airoha_pwm_config(struct airoha_pwm *pc, struct pwm_device *pwm, -+ u32 period_ticks, u32 duty_ticks) -+{ -+ unsigned int hwpwm = pwm->hwpwm; -+ int bucket, ret; -+ -+ bucket = airoha_pwm_consume_generator(pc, duty_ticks, period_ticks, -+ hwpwm); -+ if (bucket < 0) -+ return bucket; -+ -+ ret = airoha_pwm_config_flash_map(pc, hwpwm, bucket); -+ if (ret) { -+ pc->buckets[bucket].used--; -+ return ret; -+ } -+ -+ __set_bit(hwpwm, pc->initialized); -+ pc->channel_bucket[hwpwm] = bucket; -+ -+ /* -+ * SIPO are special GPIO attached to a shift register chip. The handling -+ * of this chip is internal to the SoC that takes care of applying the -+ * values based on the flash map. To apply a new flash map, it's needed -+ * to trigger a refresh on the shift register chip. -+ * If a SIPO is getting configuring , always reinit the shift register -+ * chip to make sure the correct flash map is applied. -+ * Skip reconfiguring the shift register if the related hwpwm -+ * is disabled (as it doesn't need to be mapped). -+ */ -+ if (hwpwm >= AIROHA_PWM_NUM_GPIO) { -+ ret = airoha_pwm_sipo_init(pc); -+ if (ret) { -+ airoha_pwm_release_bucket_config(pc, hwpwm); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+static void airoha_pwm_disable(struct airoha_pwm *pc, struct pwm_device *pwm) -+{ -+ /* Disable PWM and release the bucket */ -+ airoha_pwm_config_flash_map(pc, pwm->hwpwm, -1); -+ airoha_pwm_release_bucket_config(pc, pwm->hwpwm); -+ -+ __clear_bit(pwm->hwpwm, pc->initialized); -+ -+ /* If no SIPO is used, disable the shift register chip */ -+ if (!bitmap_read(pc->initialized, -+ AIROHA_PWM_NUM_GPIO, AIROHA_PWM_NUM_SIPO)) -+ regmap_clear_bits(pc->regmap, AIROHA_PWM_REG_SIPO_FLASH_MODE_CFG, -+ AIROHA_PWM_SERIAL_GPIO_FLASH_MODE); -+} -+ -+static int airoha_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, -+ const struct pwm_state *state) -+{ -+ struct airoha_pwm *pc = pwmchip_get_drvdata(chip); -+ u32 period_ticks, duty_ticks; -+ u32 period_ns, duty_ns; -+ -+ if (!state->enabled) { -+ airoha_pwm_disable(pc, pwm); -+ return 0; -+ } -+ -+ /* Only normal polarity is supported */ -+ if (state->polarity == PWM_POLARITY_INVERSED) -+ return -EINVAL; -+ -+ /* Exit early if period is less than minimum supported */ -+ if (state->period < AIROHA_PWM_PERIOD_TICK_NS) -+ return -EINVAL; -+ -+ /* Clamp period to MAX supported value */ -+ if (state->period > AIROHA_PWM_PERIOD_MAX_NS) -+ period_ns = AIROHA_PWM_PERIOD_MAX_NS; -+ else -+ period_ns = state->period; -+ -+ /* Validate duty to configured period */ -+ if (state->duty_cycle > period_ns) -+ duty_ns = period_ns; -+ else -+ duty_ns = state->duty_cycle; -+ -+ /* Convert period ns to ticks */ -+ period_ticks = airoha_pwm_get_period_ticks_from_ns(period_ns); -+ /* Convert period ticks to ns again for cosistent duty tick calculation */ -+ period_ns = airoha_pwm_get_period_ns_from_ticks(period_ticks); -+ duty_ticks = airoha_pwm_get_duty_ticks_from_ns(period_ns, duty_ns); -+ -+ return airoha_pwm_config(pc, pwm, period_ticks, duty_ticks); -+} -+ -+static int airoha_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, -+ struct pwm_state *state) -+{ -+ struct airoha_pwm *pc = pwmchip_get_drvdata(chip); -+ int ret, hwpwm = pwm->hwpwm; -+ u32 addr, shift, val; -+ u8 bucket; -+ -+ airoha_pwm_get_flash_map_addr_and_shift(hwpwm, &addr, &shift); -+ -+ ret = regmap_read(pc->regmap, addr, &val); -+ if (ret) -+ return ret; -+ -+ state->enabled = FIELD_GET(AIROHA_PWM_GPIO_FLASH_EN, val >> shift); -+ if (!state->enabled) -+ return 0; -+ -+ state->polarity = PWM_POLARITY_NORMAL; -+ -+ bucket = FIELD_GET(AIROHA_PWM_GPIO_FLASH_SET_ID, val >> shift); -+ return airoha_pwm_get_bucket(pc, bucket, &state->period, -+ &state->duty_cycle); -+} -+ -+static const struct pwm_ops airoha_pwm_ops = { -+ .apply = airoha_pwm_apply, -+ .get_state = airoha_pwm_get_state, -+}; -+ -+static int airoha_pwm_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct airoha_pwm *pc; -+ struct pwm_chip *chip; -+ int ret; -+ -+ chip = devm_pwmchip_alloc(dev, AIROHA_PWM_MAX_CHANNELS, sizeof(*pc)); -+ if (IS_ERR(chip)) -+ return PTR_ERR(chip); -+ -+ chip->ops = &airoha_pwm_ops; -+ pc = pwmchip_get_drvdata(chip); -+ -+ pc->regmap = device_node_to_regmap(dev_of_node(dev->parent)); -+ if (IS_ERR(pc->regmap)) -+ return dev_err_probe(dev, PTR_ERR(pc->regmap), "Failed to get PWM regmap\n"); -+ -+ ret = devm_pwmchip_add(dev, chip); -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to add PWM chip\n"); -+ -+ return 0; -+} -+ -+static const struct of_device_id airoha_pwm_of_match[] = { -+ { .compatible = "airoha,en7581-pwm" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, airoha_pwm_of_match); -+ -+static struct platform_driver airoha_pwm_driver = { -+ .driver = { -+ .name = "pwm-airoha", -+ .probe_type = PROBE_PREFER_ASYNCHRONOUS, -+ .of_match_table = airoha_pwm_of_match, -+ }, -+ .probe = airoha_pwm_probe, -+}; -+module_platform_driver(airoha_pwm_driver); -+ -+MODULE_AUTHOR("Lorenzo Bianconi "); -+MODULE_AUTHOR("Markus Gothe "); -+MODULE_AUTHOR("Benjamin Larsson "); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Airoha EN7581 PWM driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch b/target/linux/airoha/patches-6.12/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch deleted file mode 100644 index 8f0787c92e1..00000000000 --- a/target/linux/airoha/patches-6.12/108-v6.19-net-airoha-Add-the-capability-to-consume-out-of-orde.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 3f47e67dff1f7266e112c50313d63824f6f17102 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 6 Nov 2025 13:53:23 +0100 -Subject: [PATCH] net: airoha: Add the capability to consume out-of-order DMA - tx descriptors - -EN7581 and AN7583 SoCs are capable of DMA mapping non-linear tx skbs on -non-consecutive DMA descriptors. This feature is useful when multiple -flows are queued on the same hw tx queue since it allows to fully utilize -the available tx DMA descriptors and to avoid the starvation of -high-priority flow we have in the current codebase due to head-of-line -blocking introduced by low-priority flows. - -Tested-by: Xuegang Lu -Reviewed-by: Jacob Keller -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251106-airoha-tx-linked-list-v2-1-0706d4a322bd@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 85 +++++++++++------------- - drivers/net/ethernet/airoha/airoha_eth.h | 7 +- - 2 files changed, 45 insertions(+), 47 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -913,19 +913,13 @@ static int airoha_qdma_tx_napi_poll(stru - - dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, - DMA_TO_DEVICE); -- memset(e, 0, sizeof(*e)); -+ e->dma_addr = 0; -+ list_add_tail(&e->list, &q->tx_list); -+ - WRITE_ONCE(desc->msg0, 0); - WRITE_ONCE(desc->msg1, 0); - q->queued--; - -- /* completion ring can report out-of-order indexes if hw QoS -- * is enabled and packets with different priority are queued -- * to same DMA ring. Take into account possible out-of-order -- * reports incrementing DMA ring tail pointer -- */ -- while (q->tail != q->head && !q->entry[q->tail].dma_addr) -- q->tail = (q->tail + 1) % q->ndesc; -- - if (skb) { - u16 queue = skb_get_queue_mapping(skb); - struct netdev_queue *txq; -@@ -970,6 +964,7 @@ static int airoha_qdma_init_tx_queue(str - q->ndesc = size; - q->qdma = qdma; - q->free_thr = 1 + MAX_SKB_FRAGS; -+ INIT_LIST_HEAD(&q->tx_list); - - q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), - GFP_KERNEL); -@@ -982,9 +977,9 @@ static int airoha_qdma_init_tx_queue(str - return -ENOMEM; - - for (i = 0; i < q->ndesc; i++) { -- u32 val; -+ u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); - -- val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); -+ list_add_tail(&q->entry[i].list, &q->tx_list); - WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); - } - -@@ -994,9 +989,9 @@ static int airoha_qdma_init_tx_queue(str - - airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr); - airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, -- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); -+ FIELD_PREP(TX_RING_CPU_IDX_MASK, 0)); - airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, -- FIELD_PREP(TX_RING_DMA_IDX_MASK, q->head)); -+ FIELD_PREP(TX_RING_DMA_IDX_MASK, 0)); - - return 0; - } -@@ -1052,17 +1047,21 @@ static int airoha_qdma_init_tx(struct ai - static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) - { - struct airoha_eth *eth = q->qdma->eth; -+ int i; - - spin_lock_bh(&q->lock); -- while (q->queued) { -- struct airoha_queue_entry *e = &q->entry[q->tail]; -+ for (i = 0; i < q->ndesc; i++) { -+ struct airoha_queue_entry *e = &q->entry[i]; -+ -+ if (!e->dma_addr) -+ continue; - - dma_unmap_single(eth->dev, e->dma_addr, e->dma_len, - DMA_TO_DEVICE); - dev_kfree_skb_any(e->skb); -+ e->dma_addr = 0; - e->skb = NULL; -- -- q->tail = (q->tail + 1) % q->ndesc; -+ list_add_tail(&e->list, &q->tx_list); - q->queued--; - } - spin_unlock_bh(&q->lock); -@@ -1904,20 +1903,6 @@ static u32 airoha_get_dsa_tag(struct sk_ - #endif - } - --static bool airoha_dev_tx_queue_busy(struct airoha_queue *q, u32 nr_frags) --{ -- u32 tail = q->tail <= q->head ? q->tail + q->ndesc : q->tail; -- u32 index = q->head + nr_frags; -- -- /* completion napi can free out-of-order tx descriptors if hw QoS is -- * enabled and packets with different priorities are queued to the same -- * DMA ring. Take into account possible out-of-order reports checking -- * if the tx queue is full using circular buffer head/tail pointers -- * instead of the number of queued packets. -- */ -- return index >= tail; --} -- - static int airoha_get_fe_port(struct airoha_gdm_port *port) - { - struct airoha_qdma *qdma = port->qdma; -@@ -1940,8 +1925,10 @@ static netdev_tx_t airoha_dev_xmit(struc - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_qdma *qdma = port->qdma; - u32 nr_frags, tag, msg0, msg1, len; -+ struct airoha_queue_entry *e; - struct netdev_queue *txq; - struct airoha_queue *q; -+ LIST_HEAD(tx_list); - void *data; - int i, qid; - u16 index; -@@ -1987,7 +1974,7 @@ static netdev_tx_t airoha_dev_xmit(struc - txq = netdev_get_tx_queue(dev, qid); - nr_frags = 1 + skb_shinfo(skb)->nr_frags; - -- if (airoha_dev_tx_queue_busy(q, nr_frags)) { -+ if (q->queued + nr_frags >= q->ndesc) { - /* not enough space in the queue */ - netif_tx_stop_queue(txq); - spin_unlock_bh(&q->lock); -@@ -1996,11 +1983,13 @@ static netdev_tx_t airoha_dev_xmit(struc - - len = skb_headlen(skb); - data = skb->data; -- index = q->head; -+ -+ e = list_first_entry(&q->tx_list, struct airoha_queue_entry, -+ list); -+ index = e - q->entry; - - for (i = 0; i < nr_frags; i++) { - struct airoha_qdma_desc *desc = &q->desc[index]; -- struct airoha_queue_entry *e = &q->entry[index]; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - dma_addr_t addr; - u32 val; -@@ -2010,7 +1999,14 @@ static netdev_tx_t airoha_dev_xmit(struc - if (unlikely(dma_mapping_error(dev->dev.parent, addr))) - goto error_unmap; - -- index = (index + 1) % q->ndesc; -+ list_move_tail(&e->list, &tx_list); -+ e->skb = i ? NULL : skb; -+ e->dma_addr = addr; -+ e->dma_len = len; -+ -+ e = list_first_entry(&q->tx_list, struct airoha_queue_entry, -+ list); -+ index = e - q->entry; - - val = FIELD_PREP(QDMA_DESC_LEN_MASK, len); - if (i < nr_frags - 1) -@@ -2023,15 +2019,9 @@ static netdev_tx_t airoha_dev_xmit(struc - WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); - WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); - -- e->skb = i ? NULL : skb; -- e->dma_addr = addr; -- e->dma_len = len; -- - data = skb_frag_address(frag); - len = skb_frag_size(frag); - } -- -- q->head = index; - q->queued += i; - - skb_tx_timestamp(skb); -@@ -2040,7 +2030,7 @@ static netdev_tx_t airoha_dev_xmit(struc - if (netif_xmit_stopped(txq) || !netdev_xmit_more()) - airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), - TX_RING_CPU_IDX_MASK, -- FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); -+ FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); - - if (q->ndesc - q->queued < q->free_thr) - netif_tx_stop_queue(txq); -@@ -2050,10 +2040,13 @@ static netdev_tx_t airoha_dev_xmit(struc - return NETDEV_TX_OK; - - error_unmap: -- for (i--; i >= 0; i--) { -- index = (q->head + i) % q->ndesc; -- dma_unmap_single(dev->dev.parent, q->entry[index].dma_addr, -- q->entry[index].dma_len, DMA_TO_DEVICE); -+ while (!list_empty(&tx_list)) { -+ e = list_first_entry(&tx_list, struct airoha_queue_entry, -+ list); -+ dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len, -+ DMA_TO_DEVICE); -+ e->dma_addr = 0; -+ list_move_tail(&e->list, &q->tx_list); - } - - spin_unlock_bh(&q->lock); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -169,7 +169,10 @@ enum trtcm_param { - struct airoha_queue_entry { - union { - void *buf; -- struct sk_buff *skb; -+ struct { -+ struct list_head list; -+ struct sk_buff *skb; -+ }; - }; - dma_addr_t dma_addr; - u16 dma_len; -@@ -193,6 +196,8 @@ struct airoha_queue { - struct napi_struct napi; - struct page_pool *page_pool; - struct sk_buff *skb; -+ -+ struct list_head tx_list; - }; - - struct airoha_tx_irq_queue { diff --git a/target/linux/airoha/patches-6.12/109-01-v6.19-pinctrl-airoha-generalize-pins-group-function-confs-.patch b/target/linux/airoha/patches-6.12/109-01-v6.19-pinctrl-airoha-generalize-pins-group-function-confs-.patch deleted file mode 100644 index 9546fa3e83c..00000000000 --- a/target/linux/airoha/patches-6.12/109-01-v6.19-pinctrl-airoha-generalize-pins-group-function-confs-.patch +++ /dev/null @@ -1,775 +0,0 @@ -From 4043b0c45f8555a079bdac69a19ed08695a47a7b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Nov 2025 00:57:04 +0100 -Subject: [PATCH 1/5] pinctrl: airoha: generalize pins/group/function/confs - handling - -In preparation for support of Airoha AN7583, generalize -pins/group/function/confs handling and move them in match_data. -Inner function will base the values on the pinctrl priv struct instead of -relying on hardcoded struct. - -This permits to use different PIN data while keeping the same logic. - -Signed-off-by: Christian Marangi -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 567 ++++++++++++---------- - 1 file changed, 318 insertions(+), 249 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -30,15 +30,15 @@ - #include "../pinconf.h" - #include "../pinmux.h" - --#define PINCTRL_PIN_GROUP(id) \ -- PINCTRL_PINGROUP(#id, id##_pins, ARRAY_SIZE(id##_pins)) -+#define PINCTRL_PIN_GROUP(id, table) \ -+ PINCTRL_PINGROUP(id, table##_pins, ARRAY_SIZE(table##_pins)) - --#define PINCTRL_FUNC_DESC(id) \ -+#define PINCTRL_FUNC_DESC(id, table) \ - { \ -- .desc = PINCTRL_PINFUNCTION(#id, id##_groups, \ -- ARRAY_SIZE(id##_groups)), \ -- .groups = id##_func_group, \ -- .group_size = ARRAY_SIZE(id##_func_group), \ -+ .desc = PINCTRL_PINFUNCTION(#id, table##_groups, \ -+ ARRAY_SIZE(table##_groups)),\ -+ .groups = table##_func_group, \ -+ .group_size = ARRAY_SIZE(table##_func_group), \ - } - - #define PINCTRL_CONF_DESC(p, offset, mask) \ -@@ -357,16 +357,46 @@ struct airoha_pinctrl_gpiochip { - u32 irq_type[AIROHA_NUM_PINS]; - }; - -+struct airoha_pinctrl_confs_info { -+ const struct airoha_pinctrl_conf *confs; -+ unsigned int num_confs; -+}; -+ -+enum airoha_pinctrl_confs_type { -+ AIROHA_PINCTRL_CONFS_PULLUP, -+ AIROHA_PINCTRL_CONFS_PULLDOWN, -+ AIROHA_PINCTRL_CONFS_DRIVE_E2, -+ AIROHA_PINCTRL_CONFS_DRIVE_E4, -+ AIROHA_PINCTRL_CONFS_PCIE_RST_OD, -+ -+ AIROHA_PINCTRL_CONFS_MAX, -+}; -+ - struct airoha_pinctrl { - struct pinctrl_dev *ctrl; - -+ struct pinctrl_desc desc; -+ const struct pingroup *grps; -+ const struct airoha_pinctrl_func *funcs; -+ const struct airoha_pinctrl_confs_info *confs_info; -+ - struct regmap *chip_scu; - struct regmap *regmap; - - struct airoha_pinctrl_gpiochip gpiochip; - }; - --static struct pinctrl_pin_desc airoha_pinctrl_pins[] = { -+struct airoha_pinctrl_match_data { -+ const struct pinctrl_pin_desc *pins; -+ const unsigned int num_pins; -+ const struct pingroup *grps; -+ const unsigned int num_grps; -+ const struct airoha_pinctrl_func *funcs; -+ const unsigned int num_funcs; -+ const struct airoha_pinctrl_confs_info confs_info[AIROHA_PINCTRL_CONFS_MAX]; -+}; -+ -+static struct pinctrl_pin_desc en7581_pinctrl_pins[] = { - PINCTRL_PIN(0, "uart1_txd"), - PINCTRL_PIN(1, "uart1_rxd"), - PINCTRL_PIN(2, "i2c_scl"), -@@ -427,172 +457,172 @@ static struct pinctrl_pin_desc airoha_pi - PINCTRL_PIN(63, "pcie_reset2"), - }; - --static const int pon_pins[] = { 49, 50, 51, 52, 53, 54 }; --static const int pon_tod_1pps_pins[] = { 46 }; --static const int gsw_tod_1pps_pins[] = { 46 }; --static const int sipo_pins[] = { 16, 17 }; --static const int sipo_rclk_pins[] = { 16, 17, 43 }; --static const int mdio_pins[] = { 14, 15 }; --static const int uart2_pins[] = { 48, 55 }; --static const int uart2_cts_rts_pins[] = { 46, 47 }; --static const int hsuart_pins[] = { 28, 29 }; --static const int hsuart_cts_rts_pins[] = { 26, 27 }; --static const int uart4_pins[] = { 38, 39 }; --static const int uart5_pins[] = { 18, 19 }; --static const int i2c0_pins[] = { 2, 3 }; --static const int i2c1_pins[] = { 14, 15 }; --static const int jtag_udi_pins[] = { 16, 17, 18, 19, 20 }; --static const int jtag_dfd_pins[] = { 16, 17, 18, 19, 20 }; --static const int i2s_pins[] = { 26, 27, 28, 29 }; --static const int pcm1_pins[] = { 22, 23, 24, 25 }; --static const int pcm2_pins[] = { 18, 19, 20, 21 }; --static const int spi_quad_pins[] = { 32, 33 }; --static const int spi_pins[] = { 4, 5, 6, 7 }; --static const int spi_cs1_pins[] = { 34 }; --static const int pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 }; --static const int pcm_spi_int_pins[] = { 14 }; --static const int pcm_spi_rst_pins[] = { 15 }; --static const int pcm_spi_cs1_pins[] = { 43 }; --static const int pcm_spi_cs2_pins[] = { 40 }; --static const int pcm_spi_cs2_p128_pins[] = { 40 }; --static const int pcm_spi_cs2_p156_pins[] = { 40 }; --static const int pcm_spi_cs3_pins[] = { 41 }; --static const int pcm_spi_cs4_pins[] = { 42 }; --static const int emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 }; --static const int pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 }; --static const int gpio0_pins[] = { 13 }; --static const int gpio1_pins[] = { 14 }; --static const int gpio2_pins[] = { 15 }; --static const int gpio3_pins[] = { 16 }; --static const int gpio4_pins[] = { 17 }; --static const int gpio5_pins[] = { 18 }; --static const int gpio6_pins[] = { 19 }; --static const int gpio7_pins[] = { 20 }; --static const int gpio8_pins[] = { 21 }; --static const int gpio9_pins[] = { 22 }; --static const int gpio10_pins[] = { 23 }; --static const int gpio11_pins[] = { 24 }; --static const int gpio12_pins[] = { 25 }; --static const int gpio13_pins[] = { 26 }; --static const int gpio14_pins[] = { 27 }; --static const int gpio15_pins[] = { 28 }; --static const int gpio16_pins[] = { 29 }; --static const int gpio17_pins[] = { 30 }; --static const int gpio18_pins[] = { 31 }; --static const int gpio19_pins[] = { 32 }; --static const int gpio20_pins[] = { 33 }; --static const int gpio21_pins[] = { 34 }; --static const int gpio22_pins[] = { 35 }; --static const int gpio23_pins[] = { 36 }; --static const int gpio24_pins[] = { 37 }; --static const int gpio25_pins[] = { 38 }; --static const int gpio26_pins[] = { 39 }; --static const int gpio27_pins[] = { 40 }; --static const int gpio28_pins[] = { 41 }; --static const int gpio29_pins[] = { 42 }; --static const int gpio30_pins[] = { 43 }; --static const int gpio31_pins[] = { 44 }; --static const int gpio33_pins[] = { 46 }; --static const int gpio34_pins[] = { 47 }; --static const int gpio35_pins[] = { 48 }; --static const int gpio36_pins[] = { 49 }; --static const int gpio37_pins[] = { 50 }; --static const int gpio38_pins[] = { 51 }; --static const int gpio39_pins[] = { 52 }; --static const int gpio40_pins[] = { 53 }; --static const int gpio41_pins[] = { 54 }; --static const int gpio42_pins[] = { 55 }; --static const int gpio43_pins[] = { 56 }; --static const int gpio44_pins[] = { 57 }; --static const int gpio45_pins[] = { 58 }; --static const int gpio46_pins[] = { 59 }; --static const int pcie_reset0_pins[] = { 61 }; --static const int pcie_reset1_pins[] = { 62 }; --static const int pcie_reset2_pins[] = { 63 }; -- --static const struct pingroup airoha_pinctrl_groups[] = { -- PINCTRL_PIN_GROUP(pon), -- PINCTRL_PIN_GROUP(pon_tod_1pps), -- PINCTRL_PIN_GROUP(gsw_tod_1pps), -- PINCTRL_PIN_GROUP(sipo), -- PINCTRL_PIN_GROUP(sipo_rclk), -- PINCTRL_PIN_GROUP(mdio), -- PINCTRL_PIN_GROUP(uart2), -- PINCTRL_PIN_GROUP(uart2_cts_rts), -- PINCTRL_PIN_GROUP(hsuart), -- PINCTRL_PIN_GROUP(hsuart_cts_rts), -- PINCTRL_PIN_GROUP(uart4), -- PINCTRL_PIN_GROUP(uart5), -- PINCTRL_PIN_GROUP(i2c0), -- PINCTRL_PIN_GROUP(i2c1), -- PINCTRL_PIN_GROUP(jtag_udi), -- PINCTRL_PIN_GROUP(jtag_dfd), -- PINCTRL_PIN_GROUP(i2s), -- PINCTRL_PIN_GROUP(pcm1), -- PINCTRL_PIN_GROUP(pcm2), -- PINCTRL_PIN_GROUP(spi), -- PINCTRL_PIN_GROUP(spi_quad), -- PINCTRL_PIN_GROUP(spi_cs1), -- PINCTRL_PIN_GROUP(pcm_spi), -- PINCTRL_PIN_GROUP(pcm_spi_int), -- PINCTRL_PIN_GROUP(pcm_spi_rst), -- PINCTRL_PIN_GROUP(pcm_spi_cs1), -- PINCTRL_PIN_GROUP(pcm_spi_cs2_p128), -- PINCTRL_PIN_GROUP(pcm_spi_cs2_p156), -- PINCTRL_PIN_GROUP(pcm_spi_cs2), -- PINCTRL_PIN_GROUP(pcm_spi_cs3), -- PINCTRL_PIN_GROUP(pcm_spi_cs4), -- PINCTRL_PIN_GROUP(emmc), -- PINCTRL_PIN_GROUP(pnand), -- PINCTRL_PIN_GROUP(gpio0), -- PINCTRL_PIN_GROUP(gpio1), -- PINCTRL_PIN_GROUP(gpio2), -- PINCTRL_PIN_GROUP(gpio3), -- PINCTRL_PIN_GROUP(gpio4), -- PINCTRL_PIN_GROUP(gpio5), -- PINCTRL_PIN_GROUP(gpio6), -- PINCTRL_PIN_GROUP(gpio7), -- PINCTRL_PIN_GROUP(gpio8), -- PINCTRL_PIN_GROUP(gpio9), -- PINCTRL_PIN_GROUP(gpio10), -- PINCTRL_PIN_GROUP(gpio11), -- PINCTRL_PIN_GROUP(gpio12), -- PINCTRL_PIN_GROUP(gpio13), -- PINCTRL_PIN_GROUP(gpio14), -- PINCTRL_PIN_GROUP(gpio15), -- PINCTRL_PIN_GROUP(gpio16), -- PINCTRL_PIN_GROUP(gpio17), -- PINCTRL_PIN_GROUP(gpio18), -- PINCTRL_PIN_GROUP(gpio19), -- PINCTRL_PIN_GROUP(gpio20), -- PINCTRL_PIN_GROUP(gpio21), -- PINCTRL_PIN_GROUP(gpio22), -- PINCTRL_PIN_GROUP(gpio23), -- PINCTRL_PIN_GROUP(gpio24), -- PINCTRL_PIN_GROUP(gpio25), -- PINCTRL_PIN_GROUP(gpio26), -- PINCTRL_PIN_GROUP(gpio27), -- PINCTRL_PIN_GROUP(gpio28), -- PINCTRL_PIN_GROUP(gpio29), -- PINCTRL_PIN_GROUP(gpio30), -- PINCTRL_PIN_GROUP(gpio31), -- PINCTRL_PIN_GROUP(gpio33), -- PINCTRL_PIN_GROUP(gpio34), -- PINCTRL_PIN_GROUP(gpio35), -- PINCTRL_PIN_GROUP(gpio36), -- PINCTRL_PIN_GROUP(gpio37), -- PINCTRL_PIN_GROUP(gpio38), -- PINCTRL_PIN_GROUP(gpio39), -- PINCTRL_PIN_GROUP(gpio40), -- PINCTRL_PIN_GROUP(gpio41), -- PINCTRL_PIN_GROUP(gpio42), -- PINCTRL_PIN_GROUP(gpio43), -- PINCTRL_PIN_GROUP(gpio44), -- PINCTRL_PIN_GROUP(gpio45), -- PINCTRL_PIN_GROUP(gpio46), -- PINCTRL_PIN_GROUP(pcie_reset0), -- PINCTRL_PIN_GROUP(pcie_reset1), -- PINCTRL_PIN_GROUP(pcie_reset2), -+static const int en7581_pon_pins[] = { 49, 50, 51, 52, 53, 54 }; -+static const int en7581_pon_tod_1pps_pins[] = { 46 }; -+static const int en7581_gsw_tod_1pps_pins[] = { 46 }; -+static const int en7581_sipo_pins[] = { 16, 17 }; -+static const int en7581_sipo_rclk_pins[] = { 16, 17, 43 }; -+static const int en7581_mdio_pins[] = { 14, 15 }; -+static const int en7581_uart2_pins[] = { 48, 55 }; -+static const int en7581_uart2_cts_rts_pins[] = { 46, 47 }; -+static const int en7581_hsuart_pins[] = { 28, 29 }; -+static const int en7581_hsuart_cts_rts_pins[] = { 26, 27 }; -+static const int en7581_uart4_pins[] = { 38, 39 }; -+static const int en7581_uart5_pins[] = { 18, 19 }; -+static const int en7581_i2c0_pins[] = { 2, 3 }; -+static const int en7581_i2c1_pins[] = { 14, 15 }; -+static const int en7581_jtag_udi_pins[] = { 16, 17, 18, 19, 20 }; -+static const int en7581_jtag_dfd_pins[] = { 16, 17, 18, 19, 20 }; -+static const int en7581_i2s_pins[] = { 26, 27, 28, 29 }; -+static const int en7581_pcm1_pins[] = { 22, 23, 24, 25 }; -+static const int en7581_pcm2_pins[] = { 18, 19, 20, 21 }; -+static const int en7581_spi_quad_pins[] = { 32, 33 }; -+static const int en7581_spi_pins[] = { 4, 5, 6, 7 }; -+static const int en7581_spi_cs1_pins[] = { 34 }; -+static const int en7581_pcm_spi_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25 }; -+static const int en7581_pcm_spi_int_pins[] = { 14 }; -+static const int en7581_pcm_spi_rst_pins[] = { 15 }; -+static const int en7581_pcm_spi_cs1_pins[] = { 43 }; -+static const int en7581_pcm_spi_cs2_pins[] = { 40 }; -+static const int en7581_pcm_spi_cs2_p128_pins[] = { 40 }; -+static const int en7581_pcm_spi_cs2_p156_pins[] = { 40 }; -+static const int en7581_pcm_spi_cs3_pins[] = { 41 }; -+static const int en7581_pcm_spi_cs4_pins[] = { 42 }; -+static const int en7581_emmc_pins[] = { 4, 5, 6, 30, 31, 32, 33, 34, 35, 36, 37 }; -+static const int en7581_pnand_pins[] = { 4, 5, 6, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 }; -+static const int en7581_gpio0_pins[] = { 13 }; -+static const int en7581_gpio1_pins[] = { 14 }; -+static const int en7581_gpio2_pins[] = { 15 }; -+static const int en7581_gpio3_pins[] = { 16 }; -+static const int en7581_gpio4_pins[] = { 17 }; -+static const int en7581_gpio5_pins[] = { 18 }; -+static const int en7581_gpio6_pins[] = { 19 }; -+static const int en7581_gpio7_pins[] = { 20 }; -+static const int en7581_gpio8_pins[] = { 21 }; -+static const int en7581_gpio9_pins[] = { 22 }; -+static const int en7581_gpio10_pins[] = { 23 }; -+static const int en7581_gpio11_pins[] = { 24 }; -+static const int en7581_gpio12_pins[] = { 25 }; -+static const int en7581_gpio13_pins[] = { 26 }; -+static const int en7581_gpio14_pins[] = { 27 }; -+static const int en7581_gpio15_pins[] = { 28 }; -+static const int en7581_gpio16_pins[] = { 29 }; -+static const int en7581_gpio17_pins[] = { 30 }; -+static const int en7581_gpio18_pins[] = { 31 }; -+static const int en7581_gpio19_pins[] = { 32 }; -+static const int en7581_gpio20_pins[] = { 33 }; -+static const int en7581_gpio21_pins[] = { 34 }; -+static const int en7581_gpio22_pins[] = { 35 }; -+static const int en7581_gpio23_pins[] = { 36 }; -+static const int en7581_gpio24_pins[] = { 37 }; -+static const int en7581_gpio25_pins[] = { 38 }; -+static const int en7581_gpio26_pins[] = { 39 }; -+static const int en7581_gpio27_pins[] = { 40 }; -+static const int en7581_gpio28_pins[] = { 41 }; -+static const int en7581_gpio29_pins[] = { 42 }; -+static const int en7581_gpio30_pins[] = { 43 }; -+static const int en7581_gpio31_pins[] = { 44 }; -+static const int en7581_gpio33_pins[] = { 46 }; -+static const int en7581_gpio34_pins[] = { 47 }; -+static const int en7581_gpio35_pins[] = { 48 }; -+static const int en7581_gpio36_pins[] = { 49 }; -+static const int en7581_gpio37_pins[] = { 50 }; -+static const int en7581_gpio38_pins[] = { 51 }; -+static const int en7581_gpio39_pins[] = { 52 }; -+static const int en7581_gpio40_pins[] = { 53 }; -+static const int en7581_gpio41_pins[] = { 54 }; -+static const int en7581_gpio42_pins[] = { 55 }; -+static const int en7581_gpio43_pins[] = { 56 }; -+static const int en7581_gpio44_pins[] = { 57 }; -+static const int en7581_gpio45_pins[] = { 58 }; -+static const int en7581_gpio46_pins[] = { 59 }; -+static const int en7581_pcie_reset0_pins[] = { 61 }; -+static const int en7581_pcie_reset1_pins[] = { 62 }; -+static const int en7581_pcie_reset2_pins[] = { 63 }; -+ -+static const struct pingroup en7581_pinctrl_groups[] = { -+ PINCTRL_PIN_GROUP("pon", en7581_pon), -+ PINCTRL_PIN_GROUP("pon_tod_1pps", en7581_pon_tod_1pps), -+ PINCTRL_PIN_GROUP("gsw_tod_1pps", en7581_gsw_tod_1pps), -+ PINCTRL_PIN_GROUP("sipo", en7581_sipo), -+ PINCTRL_PIN_GROUP("sipo_rclk", en7581_sipo_rclk), -+ PINCTRL_PIN_GROUP("mdio", en7581_mdio), -+ PINCTRL_PIN_GROUP("uart2", en7581_uart2), -+ PINCTRL_PIN_GROUP("uart2_cts_rts", en7581_uart2_cts_rts), -+ PINCTRL_PIN_GROUP("hsuart", en7581_hsuart), -+ PINCTRL_PIN_GROUP("hsuart_cts_rts", en7581_hsuart_cts_rts), -+ PINCTRL_PIN_GROUP("uart4", en7581_uart4), -+ PINCTRL_PIN_GROUP("uart5", en7581_uart5), -+ PINCTRL_PIN_GROUP("i2c0", en7581_i2c0), -+ PINCTRL_PIN_GROUP("i2c1", en7581_i2c1), -+ PINCTRL_PIN_GROUP("jtag_udi", en7581_jtag_udi), -+ PINCTRL_PIN_GROUP("jtag_dfd", en7581_jtag_dfd), -+ PINCTRL_PIN_GROUP("i2s", en7581_i2s), -+ PINCTRL_PIN_GROUP("pcm1", en7581_pcm1), -+ PINCTRL_PIN_GROUP("pcm2", en7581_pcm2), -+ PINCTRL_PIN_GROUP("spi", en7581_spi), -+ PINCTRL_PIN_GROUP("spi_quad", en7581_spi_quad), -+ PINCTRL_PIN_GROUP("spi_cs1", en7581_spi_cs1), -+ PINCTRL_PIN_GROUP("pcm_spi", en7581_pcm_spi), -+ PINCTRL_PIN_GROUP("pcm_spi_int", en7581_pcm_spi_int), -+ PINCTRL_PIN_GROUP("pcm_spi_rst", en7581_pcm_spi_rst), -+ PINCTRL_PIN_GROUP("pcm_spi_cs1", en7581_pcm_spi_cs1), -+ PINCTRL_PIN_GROUP("pcm_spi_cs2_p128", en7581_pcm_spi_cs2_p128), -+ PINCTRL_PIN_GROUP("pcm_spi_cs2_p156", en7581_pcm_spi_cs2_p156), -+ PINCTRL_PIN_GROUP("pcm_spi_cs2", en7581_pcm_spi_cs2), -+ PINCTRL_PIN_GROUP("pcm_spi_cs3", en7581_pcm_spi_cs3), -+ PINCTRL_PIN_GROUP("pcm_spi_cs4", en7581_pcm_spi_cs4), -+ PINCTRL_PIN_GROUP("emmc", en7581_emmc), -+ PINCTRL_PIN_GROUP("pnand", en7581_pnand), -+ PINCTRL_PIN_GROUP("gpio0", en7581_gpio0), -+ PINCTRL_PIN_GROUP("gpio1", en7581_gpio1), -+ PINCTRL_PIN_GROUP("gpio2", en7581_gpio2), -+ PINCTRL_PIN_GROUP("gpio3", en7581_gpio3), -+ PINCTRL_PIN_GROUP("gpio4", en7581_gpio4), -+ PINCTRL_PIN_GROUP("gpio5", en7581_gpio5), -+ PINCTRL_PIN_GROUP("gpio6", en7581_gpio6), -+ PINCTRL_PIN_GROUP("gpio7", en7581_gpio7), -+ PINCTRL_PIN_GROUP("gpio8", en7581_gpio8), -+ PINCTRL_PIN_GROUP("gpio9", en7581_gpio9), -+ PINCTRL_PIN_GROUP("gpio10", en7581_gpio10), -+ PINCTRL_PIN_GROUP("gpio11", en7581_gpio11), -+ PINCTRL_PIN_GROUP("gpio12", en7581_gpio12), -+ PINCTRL_PIN_GROUP("gpio13", en7581_gpio13), -+ PINCTRL_PIN_GROUP("gpio14", en7581_gpio14), -+ PINCTRL_PIN_GROUP("gpio15", en7581_gpio15), -+ PINCTRL_PIN_GROUP("gpio16", en7581_gpio16), -+ PINCTRL_PIN_GROUP("gpio17", en7581_gpio17), -+ PINCTRL_PIN_GROUP("gpio18", en7581_gpio18), -+ PINCTRL_PIN_GROUP("gpio19", en7581_gpio19), -+ PINCTRL_PIN_GROUP("gpio20", en7581_gpio20), -+ PINCTRL_PIN_GROUP("gpio21", en7581_gpio21), -+ PINCTRL_PIN_GROUP("gpio22", en7581_gpio22), -+ PINCTRL_PIN_GROUP("gpio23", en7581_gpio23), -+ PINCTRL_PIN_GROUP("gpio24", en7581_gpio24), -+ PINCTRL_PIN_GROUP("gpio25", en7581_gpio25), -+ PINCTRL_PIN_GROUP("gpio26", en7581_gpio26), -+ PINCTRL_PIN_GROUP("gpio27", en7581_gpio27), -+ PINCTRL_PIN_GROUP("gpio28", en7581_gpio28), -+ PINCTRL_PIN_GROUP("gpio29", en7581_gpio29), -+ PINCTRL_PIN_GROUP("gpio30", en7581_gpio30), -+ PINCTRL_PIN_GROUP("gpio31", en7581_gpio31), -+ PINCTRL_PIN_GROUP("gpio33", en7581_gpio33), -+ PINCTRL_PIN_GROUP("gpio34", en7581_gpio34), -+ PINCTRL_PIN_GROUP("gpio35", en7581_gpio35), -+ PINCTRL_PIN_GROUP("gpio36", en7581_gpio36), -+ PINCTRL_PIN_GROUP("gpio37", en7581_gpio37), -+ PINCTRL_PIN_GROUP("gpio38", en7581_gpio38), -+ PINCTRL_PIN_GROUP("gpio39", en7581_gpio39), -+ PINCTRL_PIN_GROUP("gpio40", en7581_gpio40), -+ PINCTRL_PIN_GROUP("gpio41", en7581_gpio41), -+ PINCTRL_PIN_GROUP("gpio42", en7581_gpio42), -+ PINCTRL_PIN_GROUP("gpio43", en7581_gpio43), -+ PINCTRL_PIN_GROUP("gpio44", en7581_gpio44), -+ PINCTRL_PIN_GROUP("gpio45", en7581_gpio45), -+ PINCTRL_PIN_GROUP("gpio46", en7581_gpio46), -+ PINCTRL_PIN_GROUP("pcie_reset0", en7581_pcie_reset0), -+ PINCTRL_PIN_GROUP("pcie_reset1", en7581_pcie_reset1), -+ PINCTRL_PIN_GROUP("pcie_reset2", en7581_pcie_reset2), - }; - - static const char *const pon_groups[] = { "pon" }; -@@ -1955,33 +1985,33 @@ static const struct airoha_pinctrl_func_ - }, - }; - --static const struct airoha_pinctrl_func airoha_pinctrl_funcs[] = { -- PINCTRL_FUNC_DESC(pon), -- PINCTRL_FUNC_DESC(tod_1pps), -- PINCTRL_FUNC_DESC(sipo), -- PINCTRL_FUNC_DESC(mdio), -- PINCTRL_FUNC_DESC(uart), -- PINCTRL_FUNC_DESC(i2c), -- PINCTRL_FUNC_DESC(jtag), -- PINCTRL_FUNC_DESC(pcm), -- PINCTRL_FUNC_DESC(spi), -- PINCTRL_FUNC_DESC(pcm_spi), -- PINCTRL_FUNC_DESC(i2s), -- PINCTRL_FUNC_DESC(emmc), -- PINCTRL_FUNC_DESC(pnand), -- PINCTRL_FUNC_DESC(pcie_reset), -- PINCTRL_FUNC_DESC(pwm), -- PINCTRL_FUNC_DESC(phy1_led0), -- PINCTRL_FUNC_DESC(phy2_led0), -- PINCTRL_FUNC_DESC(phy3_led0), -- PINCTRL_FUNC_DESC(phy4_led0), -- PINCTRL_FUNC_DESC(phy1_led1), -- PINCTRL_FUNC_DESC(phy2_led1), -- PINCTRL_FUNC_DESC(phy3_led1), -- PINCTRL_FUNC_DESC(phy4_led1), -+static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = { -+ PINCTRL_FUNC_DESC("pon", pon), -+ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps), -+ PINCTRL_FUNC_DESC("sipo", sipo), -+ PINCTRL_FUNC_DESC("mdio", mdio), -+ PINCTRL_FUNC_DESC("uart", uart), -+ PINCTRL_FUNC_DESC("i2c", i2c), -+ PINCTRL_FUNC_DESC("jtag", jtag), -+ PINCTRL_FUNC_DESC("pcm", pcm), -+ PINCTRL_FUNC_DESC("spi", spi), -+ PINCTRL_FUNC_DESC("pcm_spi", pcm_spi), -+ PINCTRL_FUNC_DESC("i2s", i2s), -+ PINCTRL_FUNC_DESC("emmc", emmc), -+ PINCTRL_FUNC_DESC("pnand", pnand), -+ PINCTRL_FUNC_DESC("pcie_reset", pcie_reset), -+ PINCTRL_FUNC_DESC("pwm", pwm), -+ PINCTRL_FUNC_DESC("phy1_led0", phy1_led0), -+ PINCTRL_FUNC_DESC("phy2_led0", phy2_led0), -+ PINCTRL_FUNC_DESC("phy3_led0", phy3_led0), -+ PINCTRL_FUNC_DESC("phy4_led0", phy4_led0), -+ PINCTRL_FUNC_DESC("phy1_led1", phy1_led1), -+ PINCTRL_FUNC_DESC("phy2_led1", phy2_led1), -+ PINCTRL_FUNC_DESC("phy3_led1", phy3_led1), -+ PINCTRL_FUNC_DESC("phy4_led1", phy4_led1), - }; - --static const struct airoha_pinctrl_conf airoha_pinctrl_pullup_conf[] = { -+static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), - PINCTRL_CONF_DESC(2, REG_I2C_SDA_PU, I2C_SDA_PU_MASK), -@@ -2042,7 +2072,7 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK), - }; - --static const struct airoha_pinctrl_conf airoha_pinctrl_pulldown_conf[] = { -+static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), - PINCTRL_CONF_DESC(2, REG_I2C_SDA_PD, I2C_SDA_PD_MASK), -@@ -2103,7 +2133,7 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK), - }; - --static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e2_conf[] = { -+static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), - PINCTRL_CONF_DESC(2, REG_I2C_SDA_E2, I2C_SDA_E2_MASK), -@@ -2164,7 +2194,7 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK), - }; - --static const struct airoha_pinctrl_conf airoha_pinctrl_drive_e4_conf[] = { -+static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), - PINCTRL_CONF_DESC(2, REG_I2C_SDA_E4, I2C_SDA_E4_MASK), -@@ -2225,7 +2255,7 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK), - }; - --static const struct airoha_pinctrl_conf airoha_pinctrl_pcie_rst_od_conf[] = { -+static const struct airoha_pinctrl_conf en7581_pinctrl_pcie_rst_od_conf[] = { - PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), - PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), - PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK), -@@ -2547,12 +2577,17 @@ airoha_pinctrl_get_conf_reg(const struct - } - - static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl, -- const struct airoha_pinctrl_conf *conf, -- int conf_size, int pin, u32 *val) -+ enum airoha_pinctrl_confs_type conf_type, -+ int pin, u32 *val) - { -+ const struct airoha_pinctrl_confs_info *confs_info; - const struct airoha_pinctrl_reg *reg; - -- reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin); -+ confs_info = &pinctrl->confs_info[conf_type]; -+ -+ reg = airoha_pinctrl_get_conf_reg(confs_info->confs, -+ confs_info->num_confs, -+ pin); - if (!reg) - return -EINVAL; - -@@ -2565,12 +2600,17 @@ static int airoha_pinctrl_get_conf(struc - } - - static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl, -- const struct airoha_pinctrl_conf *conf, -- int conf_size, int pin, u32 val) -+ enum airoha_pinctrl_confs_type conf_type, -+ int pin, u32 val) - { -+ const struct airoha_pinctrl_confs_info *confs_info; - const struct airoha_pinctrl_reg *reg = NULL; - -- reg = airoha_pinctrl_get_conf_reg(conf, conf_size, pin); -+ confs_info = &pinctrl->confs_info[conf_type]; -+ -+ reg = airoha_pinctrl_get_conf_reg(confs_info->confs, -+ confs_info->num_confs, -+ pin); - if (!reg) - return -EINVAL; - -@@ -2583,44 +2623,34 @@ static int airoha_pinctrl_set_conf(struc - } - - #define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val) \ -- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pullup_conf, \ -- ARRAY_SIZE(airoha_pinctrl_pullup_conf), \ -+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \ - (pin), (val)) - #define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val) \ -- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pulldown_conf, \ -- ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \ -+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \ - (pin), (val)) - #define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val) \ -- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \ -- ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \ -+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \ - (pin), (val)) - #define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val) \ -- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \ -- ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \ -+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \ - (pin), (val)) - #define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val) \ -- airoha_pinctrl_get_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \ -- ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \ -+ airoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \ - (pin), (val)) - #define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val) \ -- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pullup_conf, \ -- ARRAY_SIZE(airoha_pinctrl_pullup_conf), \ -+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP, \ - (pin), (val)) - #define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val) \ -- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pulldown_conf, \ -- ARRAY_SIZE(airoha_pinctrl_pulldown_conf), \ -+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN, \ - (pin), (val)) - #define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val) \ -- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e2_conf, \ -- ARRAY_SIZE(airoha_pinctrl_drive_e2_conf), \ -+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2, \ - (pin), (val)) - #define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val) \ -- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_drive_e4_conf, \ -- ARRAY_SIZE(airoha_pinctrl_drive_e4_conf), \ -+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4, \ - (pin), (val)) - #define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val) \ -- airoha_pinctrl_set_conf((pinctrl), airoha_pinctrl_pcie_rst_od_conf, \ -- ARRAY_SIZE(airoha_pinctrl_pcie_rst_od_conf), \ -+ airoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD, \ - (pin), (val)) - - static int airoha_pinconf_get_direction(struct pinctrl_dev *pctrl_dev, u32 p) -@@ -2799,12 +2829,13 @@ static int airoha_pinconf_set(struct pin - static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev, - unsigned int group, unsigned long *config) - { -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); - u32 cur_config = 0; - int i; - -- for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) { -+ for (i = 0; i < pinctrl->grps[group].npins; i++) { - if (airoha_pinconf_get(pctrl_dev, -- airoha_pinctrl_groups[group].pins[i], -+ pinctrl->grps[group].pins[i], - config)) - return -ENOTSUPP; - -@@ -2821,13 +2852,14 @@ static int airoha_pinconf_group_set(stru - unsigned int group, unsigned long *configs, - unsigned int num_configs) - { -+ struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); - int i; - -- for (i = 0; i < airoha_pinctrl_groups[group].npins; i++) { -+ for (i = 0; i < pinctrl->grps[group].npins; i++) { - int err; - - err = airoha_pinconf_set(pctrl_dev, -- airoha_pinctrl_groups[group].pins[i], -+ pinctrl->grps[group].pins[i], - configs, num_configs); - if (err) - return err; -@@ -2853,23 +2885,16 @@ static const struct pinctrl_ops airoha_p - .dt_free_map = pinconf_generic_dt_free_map, - }; - --static struct pinctrl_desc airoha_pinctrl_desc = { -- .name = KBUILD_MODNAME, -- .owner = THIS_MODULE, -- .pctlops = &airoha_pctlops, -- .pmxops = &airoha_pmxops, -- .confops = &airoha_confops, -- .pins = airoha_pinctrl_pins, -- .npins = ARRAY_SIZE(airoha_pinctrl_pins), --}; -- - static int airoha_pinctrl_probe(struct platform_device *pdev) - { -+ const struct airoha_pinctrl_match_data *data; - struct device *dev = &pdev->dev; - struct airoha_pinctrl *pinctrl; - struct regmap *map; - int err, i; - -+ data = device_get_match_data(dev); -+ - pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL); - if (!pinctrl) - return -ENOMEM; -@@ -2884,14 +2909,23 @@ static int airoha_pinctrl_probe(struct p - - pinctrl->chip_scu = map; - -- err = devm_pinctrl_register_and_init(dev, &airoha_pinctrl_desc, -+ /* Init pinctrl desc struct */ -+ pinctrl->desc.name = KBUILD_MODNAME; -+ pinctrl->desc.owner = THIS_MODULE, -+ pinctrl->desc.pctlops = &airoha_pctlops, -+ pinctrl->desc.pmxops = &airoha_pmxops, -+ pinctrl->desc.confops = &airoha_confops, -+ pinctrl->desc.pins = data->pins, -+ pinctrl->desc.npins = data->num_pins, -+ -+ err = devm_pinctrl_register_and_init(dev, &pinctrl->desc, - pinctrl, &pinctrl->ctrl); - if (err) - return err; - - /* build pin groups */ -- for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_groups); i++) { -- const struct pingroup *grp = &airoha_pinctrl_groups[i]; -+ for (i = 0; i < data->num_grps; i++) { -+ const struct pingroup *grp = &data->grps[i]; - - err = pinctrl_generic_add_group(pinctrl->ctrl, grp->name, - grp->pins, grp->npins, -@@ -2904,10 +2938,10 @@ static int airoha_pinctrl_probe(struct p - } - - /* build functions */ -- for (i = 0; i < ARRAY_SIZE(airoha_pinctrl_funcs); i++) { -+ for (i = 0; i < data->num_funcs; i++) { - const struct airoha_pinctrl_func *func; - -- func = &airoha_pinctrl_funcs[i]; -+ func = &data->funcs[i]; - err = pinmux_generic_add_function(pinctrl->ctrl, - func->desc.name, - func->desc.groups, -@@ -2920,6 +2954,10 @@ static int airoha_pinctrl_probe(struct p - } - } - -+ pinctrl->grps = data->grps; -+ pinctrl->funcs = data->funcs; -+ pinctrl->confs_info = data->confs_info; -+ - err = pinctrl_enable(pinctrl->ctrl); - if (err) - return err; -@@ -2928,8 +2966,39 @@ static int airoha_pinctrl_probe(struct p - return airoha_pinctrl_add_gpiochip(pinctrl, pdev); - } - -+static const struct airoha_pinctrl_match_data en7581_pinctrl_match_data = { -+ .pins = en7581_pinctrl_pins, -+ .num_pins = ARRAY_SIZE(en7581_pinctrl_pins), -+ .grps = en7581_pinctrl_groups, -+ .num_grps = ARRAY_SIZE(en7581_pinctrl_groups), -+ .funcs = en7581_pinctrl_funcs, -+ .num_funcs = ARRAY_SIZE(en7581_pinctrl_funcs), -+ .confs_info = { -+ [AIROHA_PINCTRL_CONFS_PULLUP] = { -+ .confs = en7581_pinctrl_pullup_conf, -+ .num_confs = ARRAY_SIZE(en7581_pinctrl_pullup_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_PULLDOWN] = { -+ .confs = en7581_pinctrl_pulldown_conf, -+ .num_confs = ARRAY_SIZE(en7581_pinctrl_pulldown_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = { -+ .confs = en7581_pinctrl_drive_e2_conf, -+ .num_confs = ARRAY_SIZE(en7581_pinctrl_drive_e2_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = { -+ .confs = en7581_pinctrl_drive_e4_conf, -+ .num_confs = ARRAY_SIZE(en7581_pinctrl_drive_e4_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = { -+ .confs = en7581_pinctrl_pcie_rst_od_conf, -+ .num_confs = ARRAY_SIZE(en7581_pinctrl_pcie_rst_od_conf), -+ }, -+ }, -+}; -+ - static const struct of_device_id airoha_pinctrl_of_match[] = { -- { .compatible = "airoha,en7581-pinctrl" }, -+ { .compatible = "airoha,en7581-pinctrl", .data = &en7581_pinctrl_match_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, airoha_pinctrl_of_match); diff --git a/target/linux/airoha/patches-6.12/109-02-v6.19-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch b/target/linux/airoha/patches-6.12/109-02-v6.19-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch deleted file mode 100644 index 569fcafaa24..00000000000 --- a/target/linux/airoha/patches-6.12/109-02-v6.19-pinctrl-airoha-convert-PHY-LED-GPIO-to-macro.patch +++ /dev/null @@ -1,635 +0,0 @@ -From 579839c9548cf2a85e873ad787bc2fa6610bf8ab Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Nov 2025 00:57:05 +0100 -Subject: [PATCH 2/5] pinctrl: airoha: convert PHY LED GPIO to macro - -PHY LED GPIO pinctrl struct definition is very similar across the -different 4 PHY and 2 LED and it can be generelized to a macro. - -To reduce code size, convert them to a common macro. - -Signed-off-by: Christian Marangi -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 588 ++++------------------ - 1 file changed, 100 insertions(+), 488 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -1473,516 +1473,128 @@ static const struct airoha_pinctrl_func_ - }, - }; - -+#define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \ -+ { \ -+ .name = (gpio), \ -+ .regmap[0] = { \ -+ AIROHA_FUNC_MUX, \ -+ REG_GPIO_2ND_I2C_MODE, \ -+ (mux_val), \ -+ (mux_val), \ -+ }, \ -+ .regmap[1] = { \ -+ AIROHA_FUNC_MUX, \ -+ REG_LAN_LED0_MAPPING, \ -+ (map_mask), \ -+ (map_val), \ -+ }, \ -+ .regmap_size = 2, \ -+ } -+ -+#define AIROHA_PINCTRL_PHY_LED1(gpio, mux_val, map_mask, map_val) \ -+ { \ -+ .name = (gpio), \ -+ .regmap[0] = { \ -+ AIROHA_FUNC_MUX, \ -+ REG_GPIO_2ND_I2C_MODE, \ -+ (mux_val), \ -+ (mux_val), \ -+ }, \ -+ .regmap[1] = { \ -+ AIROHA_FUNC_MUX, \ -+ REG_LAN_LED1_MAPPING, \ -+ (map_mask), \ -+ (map_val), \ -+ }, \ -+ .regmap_size = 2, \ -+ } -+ - static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = { -- { -- .name = "gpio33", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED0_MODE_MASK, -- GPIO_LAN0_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio34", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED0_MODE_MASK, -- GPIO_LAN1_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio35", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED0_MODE_MASK, -- GPIO_LAN2_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio42", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), - }; - - static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = { -- { -- .name = "gpio33", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED0_MODE_MASK, -- GPIO_LAN0_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio34", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED0_MODE_MASK, -- GPIO_LAN1_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio35", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED0_MODE_MASK, -- GPIO_LAN2_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio42", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), - }; - - static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = { -- { -- .name = "gpio33", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED0_MODE_MASK, -- GPIO_LAN0_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio34", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED0_MODE_MASK, -- GPIO_LAN1_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio35", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED0_MODE_MASK, -- GPIO_LAN2_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio42", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), - }; - - static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = { -- { -- .name = "gpio33", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED0_MODE_MASK, -- GPIO_LAN0_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio34", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED0_MODE_MASK, -- GPIO_LAN1_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio35", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED0_MODE_MASK, -- GPIO_LAN2_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio42", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED0_MODE_MASK, -- GPIO_LAN3_LED0_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED0_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)), - }; - - static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = { -- { -- .name = "gpio43", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED1_MODE_MASK, -- GPIO_LAN0_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio44", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED1_MODE_MASK, -- GPIO_LAN1_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio45", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED1_MODE_MASK, -- GPIO_LAN2_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio46", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED1_MODE_MASK, -- GPIO_LAN3_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(0) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), - }; - - static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = { -- { -- .name = "gpio43", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED1_MODE_MASK, -- GPIO_LAN0_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio44", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED1_MODE_MASK, -- GPIO_LAN1_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio45", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED1_MODE_MASK, -- GPIO_LAN2_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio46", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED1_MODE_MASK, -- GPIO_LAN3_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(1) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), - }; - - static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = { -- { -- .name = "gpio43", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED1_MODE_MASK, -- GPIO_LAN0_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio44", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED1_MODE_MASK, -- GPIO_LAN1_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio45", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED1_MODE_MASK, -- GPIO_LAN2_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio46", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED1_MODE_MASK, -- GPIO_LAN3_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(2) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), - }; - - static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = { -- { -- .name = "gpio43", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN0_LED1_MODE_MASK, -- GPIO_LAN0_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN0_LED_MAPPING_MASK, -- LAN0_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio44", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN1_LED1_MODE_MASK, -- GPIO_LAN1_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN1_LED_MAPPING_MASK, -- LAN1_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio45", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN2_LED1_MODE_MASK, -- GPIO_LAN2_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN2_LED_MAPPING_MASK, -- LAN2_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, { -- .name = "gpio46", -- .regmap[0] = { -- AIROHA_FUNC_MUX, -- REG_GPIO_2ND_I2C_MODE, -- GPIO_LAN3_LED1_MODE_MASK, -- GPIO_LAN3_LED1_MODE_MASK -- }, -- .regmap[1] = { -- AIROHA_FUNC_MUX, -- REG_LAN_LED1_MAPPING, -- LAN3_LED_MAPPING_MASK, -- LAN3_PHY_LED_MAP(3) -- }, -- .regmap_size = 2, -- }, -+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), - }; - - static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = { diff --git a/target/linux/airoha/patches-6.12/109-03-v6.19-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch b/target/linux/airoha/patches-6.12/109-03-v6.19-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch deleted file mode 100644 index cab0517f7ec..00000000000 --- a/target/linux/airoha/patches-6.12/109-03-v6.19-pinctrl-airoha-convert-PWM-GPIO-to-macro.patch +++ /dev/null @@ -1,492 +0,0 @@ -From 1552ad5d649cff9d170e5bc1d13ab1487333b4b7 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Nov 2025 00:57:06 +0100 -Subject: [PATCH 3/5] pinctrl: airoha: convert PWM GPIO to macro - -The PWM GPIO struct definition follow the same pattern for every GPIO -pin hence it can be converted to a macro. - -Create 2 macro one for normal mux and one for ext mux and convert all -the entry to these new macro to reduce code size. - -Signed-off-by: Christian Marangi -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 465 ++++------------------ - 1 file changed, 68 insertions(+), 397 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -1073,404 +1073,75 @@ static const struct airoha_pinctrl_func_ - }; - - /* PWM */ -+#define AIROHA_PINCTRL_PWM(gpio, mux_val) \ -+ { \ -+ .name = (gpio), \ -+ .regmap[0] = { \ -+ AIROHA_FUNC_PWM_MUX, \ -+ REG_GPIO_FLASH_MODE_CFG, \ -+ (mux_val), \ -+ (mux_val) \ -+ }, \ -+ .regmap_size = 1, \ -+ } \ -+ -+#define AIROHA_PINCTRL_PWM_EXT(gpio, mux_val) \ -+ { \ -+ .name = (gpio), \ -+ .regmap[0] = { \ -+ AIROHA_FUNC_PWM_EXT_MUX, \ -+ REG_GPIO_FLASH_MODE_CFG_EXT, \ -+ (mux_val), \ -+ (mux_val) \ -+ }, \ -+ .regmap_size = 1, \ -+ } \ -+ - static const struct airoha_pinctrl_func_group pwm_func_group[] = { -- { -- .name = "gpio0", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO0_FLASH_MODE_CFG, -- GPIO0_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio1", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO1_FLASH_MODE_CFG, -- GPIO1_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio2", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO2_FLASH_MODE_CFG, -- GPIO2_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio3", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO3_FLASH_MODE_CFG, -- GPIO3_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio4", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO4_FLASH_MODE_CFG, -- GPIO4_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio5", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO5_FLASH_MODE_CFG, -- GPIO5_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio6", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO6_FLASH_MODE_CFG, -- GPIO6_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio7", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO7_FLASH_MODE_CFG, -- GPIO7_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio8", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO8_FLASH_MODE_CFG, -- GPIO8_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio9", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO9_FLASH_MODE_CFG, -- GPIO9_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio10", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO10_FLASH_MODE_CFG, -- GPIO10_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio11", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO11_FLASH_MODE_CFG, -- GPIO11_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio12", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO12_FLASH_MODE_CFG, -- GPIO12_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio13", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO13_FLASH_MODE_CFG, -- GPIO13_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio14", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO14_FLASH_MODE_CFG, -- GPIO14_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio15", -- .regmap[0] = { -- AIROHA_FUNC_PWM_MUX, -- REG_GPIO_FLASH_MODE_CFG, -- GPIO15_FLASH_MODE_CFG, -- GPIO15_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio16", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO16_FLASH_MODE_CFG, -- GPIO16_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio17", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO17_FLASH_MODE_CFG, -- GPIO17_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio18", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO18_FLASH_MODE_CFG, -- GPIO18_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio19", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO19_FLASH_MODE_CFG, -- GPIO19_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio20", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO20_FLASH_MODE_CFG, -- GPIO20_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio21", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO21_FLASH_MODE_CFG, -- GPIO21_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio22", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO22_FLASH_MODE_CFG, -- GPIO22_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio23", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO23_FLASH_MODE_CFG, -- GPIO23_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio24", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO24_FLASH_MODE_CFG, -- GPIO24_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio25", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO25_FLASH_MODE_CFG, -- GPIO25_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio26", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO26_FLASH_MODE_CFG, -- GPIO26_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio27", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO27_FLASH_MODE_CFG, -- GPIO27_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio28", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO28_FLASH_MODE_CFG, -- GPIO28_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio29", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO29_FLASH_MODE_CFG, -- GPIO29_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio30", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO30_FLASH_MODE_CFG, -- GPIO30_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio31", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO31_FLASH_MODE_CFG, -- GPIO31_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio36", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO36_FLASH_MODE_CFG, -- GPIO36_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio37", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO37_FLASH_MODE_CFG, -- GPIO37_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio38", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO38_FLASH_MODE_CFG, -- GPIO38_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio39", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO39_FLASH_MODE_CFG, -- GPIO39_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio40", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO40_FLASH_MODE_CFG, -- GPIO40_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio41", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO41_FLASH_MODE_CFG, -- GPIO41_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio42", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO42_FLASH_MODE_CFG, -- GPIO42_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio43", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO43_FLASH_MODE_CFG, -- GPIO43_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio44", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO44_FLASH_MODE_CFG, -- GPIO44_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio45", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO45_FLASH_MODE_CFG, -- GPIO45_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio46", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO46_FLASH_MODE_CFG, -- GPIO46_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, { -- .name = "gpio47", -- .regmap[0] = { -- AIROHA_FUNC_PWM_EXT_MUX, -- REG_GPIO_FLASH_MODE_CFG_EXT, -- GPIO47_FLASH_MODE_CFG, -- GPIO47_FLASH_MODE_CFG -- }, -- .regmap_size = 1, -- }, -+ AIROHA_PINCTRL_PWM("gpio0", GPIO0_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio1", GPIO1_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio2", GPIO2_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio3", GPIO3_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio4", GPIO4_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio5", GPIO5_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio6", GPIO6_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio7", GPIO7_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio8", GPIO8_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio9", GPIO9_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio10", GPIO10_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio11", GPIO11_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio12", GPIO12_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio13", GPIO13_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio14", GPIO14_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM("gpio15", GPIO15_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio16", GPIO16_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio17", GPIO17_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio18", GPIO18_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio19", GPIO19_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio20", GPIO20_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio21", GPIO21_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio22", GPIO22_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio23", GPIO23_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio24", GPIO24_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio25", GPIO25_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio26", GPIO26_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio27", GPIO27_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio28", GPIO28_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio29", GPIO29_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio30", GPIO30_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio31", GPIO31_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio36", GPIO36_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio37", GPIO37_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio38", GPIO38_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio39", GPIO39_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio40", GPIO40_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio41", GPIO41_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio42", GPIO42_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio43", GPIO43_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio44", GPIO44_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio45", GPIO45_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio46", GPIO46_FLASH_MODE_CFG), -+ AIROHA_PINCTRL_PWM_EXT("gpio47", GPIO47_FLASH_MODE_CFG), - }; - - #define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \ diff --git a/target/linux/airoha/patches-6.12/109-05-v6.19-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch b/target/linux/airoha/patches-6.12/109-05-v6.19-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch deleted file mode 100644 index b33af2bb78b..00000000000 --- a/target/linux/airoha/patches-6.12/109-05-v6.19-pinctrl-airoha-add-support-for-Airoha-AN7583-PINs.patch +++ /dev/null @@ -1,969 +0,0 @@ -From 3ffeb17a9a27a668efb6fbd074835e187910a9bb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Nov 2025 00:57:08 +0100 -Subject: [PATCH 5/5] pinctrl: airoha: add support for Airoha AN7583 PINs - -Add all the required entry to add suppot for Airoha AN7583 PINs. - -Where possible the same function group are used from Airoha EN7581 to -reduce code duplication. - -Signed-off-by: Christian Marangi -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 747 +++++++++++++++++++++- - 1 file changed, 740 insertions(+), 7 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -70,6 +70,7 @@ - #define GPIO_PCM_SPI_CS3_MODE_MASK BIT(20) - #define GPIO_PCM_SPI_CS2_MODE_P156_MASK BIT(19) - #define GPIO_PCM_SPI_CS2_MODE_P128_MASK BIT(18) -+#define AN7583_GPIO_PCM_SPI_CS2_MODE_MASK BIT(18) - #define GPIO_PCM_SPI_CS1_MODE_MASK BIT(17) - #define GPIO_PCM_SPI_MODE_MASK BIT(16) - #define GPIO_PCM2_MODE_MASK BIT(13) -@@ -127,6 +128,8 @@ - - /* CONF */ - #define REG_I2C_SDA_E2 0x001c -+#define AN7583_I2C1_SCL_E2_MASK BIT(16) -+#define AN7583_I2C1_SDA_E2_MASK BIT(15) - #define SPI_MISO_E2_MASK BIT(14) - #define SPI_MOSI_E2_MASK BIT(13) - #define SPI_CLK_E2_MASK BIT(12) -@@ -134,12 +137,16 @@ - #define PCIE2_RESET_E2_MASK BIT(10) - #define PCIE1_RESET_E2_MASK BIT(9) - #define PCIE0_RESET_E2_MASK BIT(8) -+#define AN7583_MDIO_0_E2_MASK BIT(5) -+#define AN7583_MDC_0_E2_MASK BIT(4) - #define UART1_RXD_E2_MASK BIT(3) - #define UART1_TXD_E2_MASK BIT(2) - #define I2C_SCL_E2_MASK BIT(1) - #define I2C_SDA_E2_MASK BIT(0) - - #define REG_I2C_SDA_E4 0x0020 -+#define AN7583_I2C1_SCL_E4_MASK BIT(16) -+#define AN7583_I2C1_SDA_E4_MASK BIT(15) - #define SPI_MISO_E4_MASK BIT(14) - #define SPI_MOSI_E4_MASK BIT(13) - #define SPI_CLK_E4_MASK BIT(12) -@@ -147,6 +154,8 @@ - #define PCIE2_RESET_E4_MASK BIT(10) - #define PCIE1_RESET_E4_MASK BIT(9) - #define PCIE0_RESET_E4_MASK BIT(8) -+#define AN7583_MDIO_0_E4_MASK BIT(5) -+#define AN7583_MDC_0_E4_MASK BIT(4) - #define UART1_RXD_E4_MASK BIT(3) - #define UART1_TXD_E4_MASK BIT(2) - #define I2C_SCL_E4_MASK BIT(1) -@@ -158,6 +167,8 @@ - #define REG_GPIO_H_E4 0x0030 - - #define REG_I2C_SDA_PU 0x0044 -+#define AN7583_I2C1_SCL_PU_MASK BIT(16) -+#define AN7583_I2C1_SDA_PU_MASK BIT(15) - #define SPI_MISO_PU_MASK BIT(14) - #define SPI_MOSI_PU_MASK BIT(13) - #define SPI_CLK_PU_MASK BIT(12) -@@ -165,12 +176,16 @@ - #define PCIE2_RESET_PU_MASK BIT(10) - #define PCIE1_RESET_PU_MASK BIT(9) - #define PCIE0_RESET_PU_MASK BIT(8) -+#define AN7583_MDIO_0_PU_MASK BIT(5) -+#define AN7583_MDC_0_PU_MASK BIT(4) - #define UART1_RXD_PU_MASK BIT(3) - #define UART1_TXD_PU_MASK BIT(2) - #define I2C_SCL_PU_MASK BIT(1) - #define I2C_SDA_PU_MASK BIT(0) - - #define REG_I2C_SDA_PD 0x0048 -+#define AN7583_I2C1_SDA_PD_MASK BIT(16) -+#define AN7583_I2C1_SCL_PD_MASK BIT(15) - #define SPI_MISO_PD_MASK BIT(14) - #define SPI_MOSI_PD_MASK BIT(13) - #define SPI_CLK_PD_MASK BIT(12) -@@ -178,6 +193,8 @@ - #define PCIE2_RESET_PD_MASK BIT(10) - #define PCIE1_RESET_PD_MASK BIT(9) - #define PCIE0_RESET_PD_MASK BIT(8) -+#define AN7583_MDIO_0_PD_MASK BIT(5) -+#define AN7583_MDC_0_PD_MASK BIT(4) - #define UART1_RXD_PD_MASK BIT(3) - #define UART1_TXD_PD_MASK BIT(2) - #define I2C_SCL_PD_MASK BIT(1) -@@ -625,10 +642,223 @@ static const struct pingroup en7581_pinc - PINCTRL_PIN_GROUP("pcie_reset2", en7581_pcie_reset2), - }; - -+static struct pinctrl_pin_desc an7583_pinctrl_pins[] = { -+ PINCTRL_PIN(2, "gpio0"), -+ PINCTRL_PIN(3, "gpio1"), -+ PINCTRL_PIN(4, "gpio2"), -+ PINCTRL_PIN(5, "gpio3"), -+ PINCTRL_PIN(6, "gpio4"), -+ PINCTRL_PIN(7, "gpio5"), -+ PINCTRL_PIN(8, "gpio6"), -+ PINCTRL_PIN(9, "gpio7"), -+ PINCTRL_PIN(10, "gpio8"), -+ PINCTRL_PIN(11, "gpio9"), -+ PINCTRL_PIN(12, "gpio10"), -+ PINCTRL_PIN(13, "gpio11"), -+ PINCTRL_PIN(14, "gpio12"), -+ PINCTRL_PIN(15, "gpio13"), -+ PINCTRL_PIN(16, "gpio14"), -+ PINCTRL_PIN(17, "gpio15"), -+ PINCTRL_PIN(18, "gpio16"), -+ PINCTRL_PIN(19, "gpio17"), -+ PINCTRL_PIN(20, "gpio18"), -+ PINCTRL_PIN(21, "gpio19"), -+ PINCTRL_PIN(22, "gpio20"), -+ PINCTRL_PIN(23, "gpio21"), -+ PINCTRL_PIN(24, "gpio22"), -+ PINCTRL_PIN(25, "gpio23"), -+ PINCTRL_PIN(26, "gpio24"), -+ PINCTRL_PIN(27, "gpio25"), -+ PINCTRL_PIN(28, "gpio26"), -+ PINCTRL_PIN(29, "gpio27"), -+ PINCTRL_PIN(30, "gpio28"), -+ PINCTRL_PIN(31, "gpio29"), -+ PINCTRL_PIN(32, "gpio30"), -+ PINCTRL_PIN(33, "gpio31"), -+ PINCTRL_PIN(34, "gpio32"), -+ PINCTRL_PIN(35, "gpio33"), -+ PINCTRL_PIN(36, "gpio34"), -+ PINCTRL_PIN(37, "gpio35"), -+ PINCTRL_PIN(38, "gpio36"), -+ PINCTRL_PIN(39, "gpio37"), -+ PINCTRL_PIN(40, "gpio38"), -+ PINCTRL_PIN(41, "i2c0_scl"), -+ PINCTRL_PIN(42, "i2c0_sda"), -+ PINCTRL_PIN(43, "i2c1_scl"), -+ PINCTRL_PIN(44, "i2c1_sda"), -+ PINCTRL_PIN(45, "spi_clk"), -+ PINCTRL_PIN(46, "spi_cs"), -+ PINCTRL_PIN(47, "spi_mosi"), -+ PINCTRL_PIN(48, "spi_miso"), -+ PINCTRL_PIN(49, "uart_txd"), -+ PINCTRL_PIN(50, "uart_rxd"), -+ PINCTRL_PIN(51, "pcie_reset0"), -+ PINCTRL_PIN(52, "pcie_reset1"), -+ PINCTRL_PIN(53, "mdc_0"), -+ PINCTRL_PIN(54, "mdio_0"), -+}; -+ -+static const int an7583_pon_pins[] = { 15, 16, 17, 18, 19, 20 }; -+static const int an7583_pon_tod_1pps_pins[] = { 32 }; -+static const int an7583_gsw_tod_1pps_pins[] = { 32 }; -+static const int an7583_sipo_pins[] = { 34, 35 }; -+static const int an7583_sipo_rclk_pins[] = { 34, 35, 33 }; -+static const int an7583_mdio_pins[] = { 43, 44 }; -+static const int an7583_uart2_pins[] = { 34, 35 }; -+static const int an7583_uart2_cts_rts_pins[] = { 32, 33 }; -+static const int an7583_hsuart_pins[] = { 30, 31 }; -+static const int an7583_hsuart_cts_rts_pins[] = { 28, 29 }; -+static const int an7583_npu_uart_pins[] = { 7, 8 }; -+static const int an7583_uart4_pins[] = { 7, 8 }; -+static const int an7583_uart5_pins[] = { 23, 24 }; -+static const int an7583_i2c0_pins[] = { 41, 42 }; -+static const int an7583_i2c1_pins[] = { 43, 44 }; -+static const int an7583_jtag_udi_pins[] = { 23, 24, 22, 25, 26 }; -+static const int an7583_jtag_dfd_pins[] = { 23, 24, 22, 25, 26 }; -+static const int an7583_pcm1_pins[] = { 10, 11, 12, 13, 14 }; -+static const int an7583_pcm2_pins[] = { 28, 29, 30, 31, 24 }; -+static const int an7583_spi_pins[] = { 28, 29, 30, 31 }; -+static const int an7583_spi_quad_pins[] = { 25, 26 }; -+static const int an7583_spi_cs1_pins[] = { 27 }; -+static const int an7583_pcm_spi_pins[] = { 28, 29, 30, 31, 10, 11, 12, 13 }; -+static const int an7583_pcm_spi_rst_pins[] = { 14 }; -+static const int an7583_pcm_spi_cs1_pins[] = { 24 }; -+static const int an7583_emmc_pins[] = { 7, 8, 9, 22, 23, 24, 25, 26, 45, 46, 47 }; -+static const int an7583_pnand_pins[] = { 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 45, 46, 47, 48 }; -+static const int an7583_gpio0_pins[] = { 2 }; -+static const int an7583_gpio1_pins[] = { 3 }; -+static const int an7583_gpio2_pins[] = { 4 }; -+static const int an7583_gpio3_pins[] = { 5 }; -+static const int an7583_gpio4_pins[] = { 6 }; -+static const int an7583_gpio5_pins[] = { 7 }; -+static const int an7583_gpio6_pins[] = { 8 }; -+static const int an7583_gpio7_pins[] = { 9 }; -+static const int an7583_gpio8_pins[] = { 10 }; -+static const int an7583_gpio9_pins[] = { 11 }; -+static const int an7583_gpio10_pins[] = { 12 }; -+static const int an7583_gpio11_pins[] = { 13 }; -+static const int an7583_gpio12_pins[] = { 14 }; -+static const int an7583_gpio13_pins[] = { 15 }; -+static const int an7583_gpio14_pins[] = { 16 }; -+static const int an7583_gpio15_pins[] = { 17 }; -+static const int an7583_gpio16_pins[] = { 18 }; -+static const int an7583_gpio17_pins[] = { 19 }; -+static const int an7583_gpio18_pins[] = { 20 }; -+static const int an7583_gpio19_pins[] = { 21 }; -+static const int an7583_gpio20_pins[] = { 22 }; -+static const int an7583_gpio21_pins[] = { 24 }; -+static const int an7583_gpio23_pins[] = { 25 }; -+static const int an7583_gpio24_pins[] = { 26 }; -+static const int an7583_gpio25_pins[] = { 27 }; -+static const int an7583_gpio26_pins[] = { 28 }; -+static const int an7583_gpio27_pins[] = { 29 }; -+static const int an7583_gpio28_pins[] = { 30 }; -+static const int an7583_gpio29_pins[] = { 31 }; -+static const int an7583_gpio30_pins[] = { 32 }; -+static const int an7583_gpio31_pins[] = { 33 }; -+static const int an7583_gpio33_pins[] = { 35 }; -+static const int an7583_gpio34_pins[] = { 36 }; -+static const int an7583_gpio35_pins[] = { 37 }; -+static const int an7583_gpio36_pins[] = { 38 }; -+static const int an7583_gpio37_pins[] = { 39 }; -+static const int an7583_gpio38_pins[] = { 40 }; -+static const int an7583_gpio39_pins[] = { 41 }; -+static const int an7583_gpio40_pins[] = { 42 }; -+static const int an7583_gpio41_pins[] = { 43 }; -+static const int an7583_gpio42_pins[] = { 44 }; -+static const int an7583_gpio43_pins[] = { 45 }; -+static const int an7583_gpio44_pins[] = { 46 }; -+static const int an7583_gpio45_pins[] = { 47 }; -+static const int an7583_gpio46_pins[] = { 48 }; -+static const int an7583_gpio47_pins[] = { 49 }; -+static const int an7583_gpio48_pins[] = { 50 }; -+static const int an7583_pcie_reset0_pins[] = { 51 }; -+static const int an7583_pcie_reset1_pins[] = { 52 }; -+ -+static const struct pingroup an7583_pinctrl_groups[] = { -+ PINCTRL_PIN_GROUP("pon", an7583_pon), -+ PINCTRL_PIN_GROUP("pon_tod_1pps", an7583_pon_tod_1pps), -+ PINCTRL_PIN_GROUP("gsw_tod_1pps", an7583_gsw_tod_1pps), -+ PINCTRL_PIN_GROUP("sipo", an7583_sipo), -+ PINCTRL_PIN_GROUP("sipo_rclk", an7583_sipo_rclk), -+ PINCTRL_PIN_GROUP("mdio", an7583_mdio), -+ PINCTRL_PIN_GROUP("uart2", an7583_uart2), -+ PINCTRL_PIN_GROUP("uart2_cts_rts", an7583_uart2_cts_rts), -+ PINCTRL_PIN_GROUP("hsuart", an7583_hsuart), -+ PINCTRL_PIN_GROUP("hsuart_cts_rts", an7583_hsuart_cts_rts), -+ PINCTRL_PIN_GROUP("npu_uart", an7583_npu_uart), -+ PINCTRL_PIN_GROUP("uart4", an7583_uart4), -+ PINCTRL_PIN_GROUP("uart5", an7583_uart5), -+ PINCTRL_PIN_GROUP("i2c0", an7583_i2c0), -+ PINCTRL_PIN_GROUP("i2c1", an7583_i2c1), -+ PINCTRL_PIN_GROUP("jtag_udi", an7583_jtag_udi), -+ PINCTRL_PIN_GROUP("jtag_dfd", an7583_jtag_dfd), -+ PINCTRL_PIN_GROUP("pcm1", an7583_pcm1), -+ PINCTRL_PIN_GROUP("pcm2", an7583_pcm2), -+ PINCTRL_PIN_GROUP("spi", an7583_spi), -+ PINCTRL_PIN_GROUP("spi_quad", an7583_spi_quad), -+ PINCTRL_PIN_GROUP("spi_cs1", an7583_spi_cs1), -+ PINCTRL_PIN_GROUP("pcm_spi", an7583_pcm_spi), -+ PINCTRL_PIN_GROUP("pcm_spi_rst", an7583_pcm_spi_rst), -+ PINCTRL_PIN_GROUP("pcm_spi_cs1", an7583_pcm_spi_cs1), -+ PINCTRL_PIN_GROUP("emmc", an7583_emmc), -+ PINCTRL_PIN_GROUP("pnand", an7583_pnand), -+ PINCTRL_PIN_GROUP("gpio0", an7583_gpio0), -+ PINCTRL_PIN_GROUP("gpio1", an7583_gpio1), -+ PINCTRL_PIN_GROUP("gpio2", an7583_gpio2), -+ PINCTRL_PIN_GROUP("gpio3", an7583_gpio3), -+ PINCTRL_PIN_GROUP("gpio4", an7583_gpio4), -+ PINCTRL_PIN_GROUP("gpio5", an7583_gpio5), -+ PINCTRL_PIN_GROUP("gpio6", an7583_gpio6), -+ PINCTRL_PIN_GROUP("gpio7", an7583_gpio7), -+ PINCTRL_PIN_GROUP("gpio8", an7583_gpio8), -+ PINCTRL_PIN_GROUP("gpio9", an7583_gpio9), -+ PINCTRL_PIN_GROUP("gpio10", an7583_gpio10), -+ PINCTRL_PIN_GROUP("gpio11", an7583_gpio11), -+ PINCTRL_PIN_GROUP("gpio12", an7583_gpio12), -+ PINCTRL_PIN_GROUP("gpio13", an7583_gpio13), -+ PINCTRL_PIN_GROUP("gpio14", an7583_gpio14), -+ PINCTRL_PIN_GROUP("gpio15", an7583_gpio15), -+ PINCTRL_PIN_GROUP("gpio16", an7583_gpio16), -+ PINCTRL_PIN_GROUP("gpio17", an7583_gpio17), -+ PINCTRL_PIN_GROUP("gpio18", an7583_gpio18), -+ PINCTRL_PIN_GROUP("gpio19", an7583_gpio19), -+ PINCTRL_PIN_GROUP("gpio20", an7583_gpio20), -+ PINCTRL_PIN_GROUP("gpio21", an7583_gpio21), -+ PINCTRL_PIN_GROUP("gpio23", an7583_gpio23), -+ PINCTRL_PIN_GROUP("gpio24", an7583_gpio24), -+ PINCTRL_PIN_GROUP("gpio25", an7583_gpio25), -+ PINCTRL_PIN_GROUP("gpio26", an7583_gpio26), -+ PINCTRL_PIN_GROUP("gpio27", an7583_gpio27), -+ PINCTRL_PIN_GROUP("gpio28", an7583_gpio28), -+ PINCTRL_PIN_GROUP("gpio29", an7583_gpio29), -+ PINCTRL_PIN_GROUP("gpio30", an7583_gpio30), -+ PINCTRL_PIN_GROUP("gpio31", an7583_gpio31), -+ PINCTRL_PIN_GROUP("gpio33", an7583_gpio33), -+ PINCTRL_PIN_GROUP("gpio34", an7583_gpio34), -+ PINCTRL_PIN_GROUP("gpio35", an7583_gpio35), -+ PINCTRL_PIN_GROUP("gpio36", an7583_gpio36), -+ PINCTRL_PIN_GROUP("gpio37", an7583_gpio37), -+ PINCTRL_PIN_GROUP("gpio38", an7583_gpio38), -+ PINCTRL_PIN_GROUP("gpio39", an7583_gpio39), -+ PINCTRL_PIN_GROUP("gpio40", an7583_gpio40), -+ PINCTRL_PIN_GROUP("gpio41", an7583_gpio41), -+ PINCTRL_PIN_GROUP("gpio42", an7583_gpio42), -+ PINCTRL_PIN_GROUP("gpio43", an7583_gpio43), -+ PINCTRL_PIN_GROUP("gpio44", an7583_gpio44), -+ PINCTRL_PIN_GROUP("gpio45", an7583_gpio45), -+ PINCTRL_PIN_GROUP("gpio46", an7583_gpio46), -+ PINCTRL_PIN_GROUP("gpio47", an7583_gpio47), -+ PINCTRL_PIN_GROUP("gpio48", an7583_gpio48), -+ PINCTRL_PIN_GROUP("pcie_reset0", an7583_pcie_reset0), -+ PINCTRL_PIN_GROUP("pcie_reset1", an7583_pcie_reset1), -+}; -+ - static const char *const pon_groups[] = { "pon" }; - static const char *const tod_1pps_groups[] = { "pon_tod_1pps", "gsw_tod_1pps" }; - static const char *const sipo_groups[] = { "sipo", "sipo_rclk" }; - static const char *const mdio_groups[] = { "mdio" }; -+static const char *const an7583_mdio_groups[] = { "mdio" }; - static const char *const uart_groups[] = { "uart2", "uart2_cts_rts", "hsuart", - "hsuart_cts_rts", "uart4", - "uart5" }; -@@ -641,11 +871,16 @@ static const char *const pcm_spi_groups[ - "pcm_spi_cs2_p156", - "pcm_spi_cs2_p128", - "pcm_spi_cs3", "pcm_spi_cs4" }; -+static const char *const an7583_pcm_spi_groups[] = { "pcm_spi", "pcm_spi_int", -+ "pcm_spi_rst", "pcm_spi_cs1", -+ "pcm_spi_cs2", "pcm_spi_cs3", -+ "pcm_spi_cs4" }; - static const char *const i2s_groups[] = { "i2s" }; - static const char *const emmc_groups[] = { "emmc" }; - static const char *const pnand_groups[] = { "pnand" }; - static const char *const pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1", - "pcie_reset2" }; -+static const char *const an7583_pcie_reset_groups[] = { "pcie_reset0", "pcie_reset1" }; - static const char *const pwm_groups[] = { "gpio0", "gpio1", - "gpio2", "gpio3", - "gpio4", "gpio5", -@@ -684,6 +919,22 @@ static const char *const phy3_led1_group - "gpio45", "gpio46" }; - static const char *const phy4_led1_groups[] = { "gpio43", "gpio44", - "gpio45", "gpio46" }; -+static const char *const an7583_phy1_led0_groups[] = { "gpio1", "gpio2", -+ "gpio3", "gpio4" }; -+static const char *const an7583_phy2_led0_groups[] = { "gpio1", "gpio2", -+ "gpio3", "gpio4" }; -+static const char *const an7583_phy3_led0_groups[] = { "gpio1", "gpio2", -+ "gpio3", "gpio4" }; -+static const char *const an7583_phy4_led0_groups[] = { "gpio1", "gpio2", -+ "gpio3", "gpio4" }; -+static const char *const an7583_phy1_led1_groups[] = { "gpio8", "gpio9", -+ "gpio10", "gpio11" }; -+static const char *const an7583_phy2_led1_groups[] = { "gpio8", "gpio9", -+ "gpio10", "gpio11" }; -+static const char *const an7583_phy3_led1_groups[] = { "gpio8", "gpio9", -+ "gpio10", "gpio11" }; -+static const char *const an7583_phy4_led1_groups[] = { "gpio8", "gpio9", -+ "gpio10", "gpio11" }; - - static const struct airoha_pinctrl_func_group pon_func_group[] = { - { -@@ -761,6 +1012,25 @@ static const struct airoha_pinctrl_func_ - }, - }; - -+static const struct airoha_pinctrl_func_group an7583_mdio_func_group[] = { -+ { -+ .name = "mdio", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_SGMII_MDIO_MODE_MASK, -+ GPIO_SGMII_MDIO_MODE_MASK -+ }, -+ .regmap[1] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_MDC_IO_MASTER_MODE_MODE, -+ GPIO_MDC_IO_MASTER_MODE_MODE -+ }, -+ .regmap_size = 2, -+ }, -+}; -+ - static const struct airoha_pinctrl_func_group uart_func_group[] = { - { - .name = "uart2", -@@ -1002,6 +1272,73 @@ static const struct airoha_pinctrl_func_ - }, - }; - -+static const struct airoha_pinctrl_func_group an7583_pcm_spi_func_group[] = { -+ { -+ .name = "pcm_spi", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_MODE_MASK, -+ GPIO_PCM_SPI_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_int", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_INT_MODE_MASK, -+ GPIO_PCM_INT_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_rst", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_RESET_MODE_MASK, -+ GPIO_PCM_RESET_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs1", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS1_MODE_MASK, -+ GPIO_PCM_SPI_CS1_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs2", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ AN7583_GPIO_PCM_SPI_CS2_MODE_MASK, -+ AN7583_GPIO_PCM_SPI_CS2_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs3", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS3_MODE_MASK, -+ GPIO_PCM_SPI_CS3_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcm_spi_cs4", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_SPI_CS1_MODE, -+ GPIO_PCM_SPI_CS4_MODE_MASK, -+ GPIO_PCM_SPI_CS4_MODE_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ - static const struct airoha_pinctrl_func_group i2s_func_group[] = { - { - .name = "i2s", -@@ -1072,6 +1409,28 @@ static const struct airoha_pinctrl_func_ - }, - }; - -+static const struct airoha_pinctrl_func_group an7583_pcie_reset_func_group[] = { -+ { -+ .name = "pcie_reset0", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_PCIE_RESET0_MASK, -+ GPIO_PCIE_RESET0_MASK -+ }, -+ .regmap_size = 1, -+ }, { -+ .name = "pcie_reset1", -+ .regmap[0] = { -+ AIROHA_FUNC_MUX, -+ REG_GPIO_PON_MODE, -+ GPIO_PCIE_RESET1_MASK, -+ GPIO_PCIE_RESET1_MASK -+ }, -+ .regmap_size = 1, -+ }, -+}; -+ - /* PWM */ - #define AIROHA_PINCTRL_PWM(gpio, mux_val) \ - { \ -@@ -1268,6 +1627,94 @@ static const struct airoha_pinctrl_func_ - LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), - }; - -+static const struct airoha_pinctrl_func_group an7583_phy1_led0_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), -+}; -+ -+static const struct airoha_pinctrl_func_group an7583_phy2_led0_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), -+}; -+ -+static const struct airoha_pinctrl_func_group an7583_phy3_led0_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), -+}; -+ -+static const struct airoha_pinctrl_func_group an7583_phy4_led0_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)), -+}; -+ -+static const struct airoha_pinctrl_func_group an7583_phy1_led1_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED1("gpio1", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), -+}; -+ -+static const struct airoha_pinctrl_func_group an7583_phy2_led1_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), -+}; -+ -+static const struct airoha_pinctrl_func_group an7583_phy3_led1_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), -+}; -+ -+static const struct airoha_pinctrl_func_group an7583_phy4_led1_func_group[] = { -+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), -+}; -+ - static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = { - PINCTRL_FUNC_DESC("pon", pon), - PINCTRL_FUNC_DESC("tod_1pps", tod_1pps), -@@ -1294,6 +1741,31 @@ static const struct airoha_pinctrl_func - PINCTRL_FUNC_DESC("phy4_led1", phy4_led1), - }; - -+static const struct airoha_pinctrl_func an7583_pinctrl_funcs[] = { -+ PINCTRL_FUNC_DESC("pon", pon), -+ PINCTRL_FUNC_DESC("tod_1pps", tod_1pps), -+ PINCTRL_FUNC_DESC("sipo", sipo), -+ PINCTRL_FUNC_DESC("mdio", an7583_mdio), -+ PINCTRL_FUNC_DESC("uart", uart), -+ PINCTRL_FUNC_DESC("i2c", i2c), -+ PINCTRL_FUNC_DESC("jtag", jtag), -+ PINCTRL_FUNC_DESC("pcm", pcm), -+ PINCTRL_FUNC_DESC("spi", spi), -+ PINCTRL_FUNC_DESC("pcm_spi", an7583_pcm_spi), -+ PINCTRL_FUNC_DESC("emmc", emmc), -+ PINCTRL_FUNC_DESC("pnand", pnand), -+ PINCTRL_FUNC_DESC("pcie_reset", an7583_pcie_reset), -+ PINCTRL_FUNC_DESC("pwm", pwm), -+ PINCTRL_FUNC_DESC("phy1_led0", an7583_phy1_led0), -+ PINCTRL_FUNC_DESC("phy2_led0", an7583_phy2_led0), -+ PINCTRL_FUNC_DESC("phy3_led0", an7583_phy3_led0), -+ PINCTRL_FUNC_DESC("phy4_led0", an7583_phy4_led0), -+ PINCTRL_FUNC_DESC("phy1_led1", an7583_phy1_led1), -+ PINCTRL_FUNC_DESC("phy2_led1", an7583_phy2_led1), -+ PINCTRL_FUNC_DESC("phy3_led1", an7583_phy3_led1), -+ PINCTRL_FUNC_DESC("phy4_led1", an7583_phy4_led1), -+}; -+ - static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), -@@ -1355,6 +1827,62 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK), - }; - -+static const struct airoha_pinctrl_conf an7583_pinctrl_pullup_conf[] = { -+ PINCTRL_CONF_DESC(2, REG_GPIO_L_PU, BIT(0)), -+ PINCTRL_CONF_DESC(3, REG_GPIO_L_PU, BIT(1)), -+ PINCTRL_CONF_DESC(4, REG_GPIO_L_PU, BIT(2)), -+ PINCTRL_CONF_DESC(5, REG_GPIO_L_PU, BIT(3)), -+ PINCTRL_CONF_DESC(6, REG_GPIO_L_PU, BIT(4)), -+ PINCTRL_CONF_DESC(7, REG_GPIO_L_PU, BIT(5)), -+ PINCTRL_CONF_DESC(8, REG_GPIO_L_PU, BIT(6)), -+ PINCTRL_CONF_DESC(9, REG_GPIO_L_PU, BIT(7)), -+ PINCTRL_CONF_DESC(10, REG_GPIO_L_PU, BIT(8)), -+ PINCTRL_CONF_DESC(11, REG_GPIO_L_PU, BIT(9)), -+ PINCTRL_CONF_DESC(12, REG_GPIO_L_PU, BIT(10)), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PU, BIT(11)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PU, BIT(12)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PU, BIT(13)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PU, BIT(14)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PU, BIT(15)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PU, BIT(16)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PU, BIT(17)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PU, BIT(18)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PU, BIT(18)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PU, BIT(20)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PU, BIT(21)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PU, BIT(22)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PU, BIT(23)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PU, BIT(24)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PU, BIT(25)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PU, BIT(26)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PU, BIT(27)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PU, BIT(28)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PU, BIT(29)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PU, BIT(30)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PU, BIT(31)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_H_PU, BIT(0)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_H_PU, BIT(1)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_H_PU, BIT(2)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_H_PU, BIT(3)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_H_PU, BIT(4)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_H_PU, BIT(5)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_H_PU, BIT(6)), -+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PU, I2C_SCL_PU_MASK), -+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PU, I2C_SDA_PU_MASK), -+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PU, AN7583_I2C1_SCL_PU_MASK), -+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PU, AN7583_I2C1_SDA_PU_MASK), -+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PU, SPI_CLK_PU_MASK), -+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PU, SPI_CS0_PU_MASK), -+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PU, SPI_MOSI_PU_MASK), -+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PU, SPI_MISO_PU_MASK), -+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PU, UART1_TXD_PU_MASK), -+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PU, UART1_RXD_PU_MASK), -+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PU, PCIE0_RESET_PU_MASK), -+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PU, PCIE1_RESET_PU_MASK), -+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PU, AN7583_MDC_0_PU_MASK), -+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PU, AN7583_MDIO_0_PU_MASK), -+}; -+ - static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), -@@ -1416,6 +1944,62 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK), - }; - -+static const struct airoha_pinctrl_conf an7583_pinctrl_pulldown_conf[] = { -+ PINCTRL_CONF_DESC(2, REG_GPIO_L_PD, BIT(0)), -+ PINCTRL_CONF_DESC(3, REG_GPIO_L_PD, BIT(1)), -+ PINCTRL_CONF_DESC(4, REG_GPIO_L_PD, BIT(2)), -+ PINCTRL_CONF_DESC(5, REG_GPIO_L_PD, BIT(3)), -+ PINCTRL_CONF_DESC(6, REG_GPIO_L_PD, BIT(4)), -+ PINCTRL_CONF_DESC(7, REG_GPIO_L_PD, BIT(5)), -+ PINCTRL_CONF_DESC(8, REG_GPIO_L_PD, BIT(6)), -+ PINCTRL_CONF_DESC(9, REG_GPIO_L_PD, BIT(7)), -+ PINCTRL_CONF_DESC(10, REG_GPIO_L_PD, BIT(8)), -+ PINCTRL_CONF_DESC(11, REG_GPIO_L_PD, BIT(9)), -+ PINCTRL_CONF_DESC(12, REG_GPIO_L_PD, BIT(10)), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_PD, BIT(11)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_PD, BIT(12)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_PD, BIT(13)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_PD, BIT(14)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_PD, BIT(15)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_PD, BIT(16)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_PD, BIT(17)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_PD, BIT(18)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_PD, BIT(18)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_PD, BIT(20)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_PD, BIT(21)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_PD, BIT(22)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_PD, BIT(23)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_PD, BIT(24)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_PD, BIT(25)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_PD, BIT(26)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_PD, BIT(27)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_PD, BIT(28)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_PD, BIT(29)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_PD, BIT(30)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_PD, BIT(31)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_H_PD, BIT(0)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_H_PD, BIT(1)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_H_PD, BIT(2)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_H_PD, BIT(3)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_H_PD, BIT(4)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_H_PD, BIT(5)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_H_PD, BIT(6)), -+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_PD, I2C_SCL_PD_MASK), -+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_PD, I2C_SDA_PD_MASK), -+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_PD, AN7583_I2C1_SCL_PD_MASK), -+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_PD, AN7583_I2C1_SDA_PD_MASK), -+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_PD, SPI_CLK_PD_MASK), -+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_PD, SPI_CS0_PD_MASK), -+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_PD, SPI_MOSI_PD_MASK), -+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_PD, SPI_MISO_PD_MASK), -+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_PD, UART1_TXD_PD_MASK), -+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_PD, UART1_RXD_PD_MASK), -+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_PD, PCIE0_RESET_PD_MASK), -+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_PD, PCIE1_RESET_PD_MASK), -+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_PD, AN7583_MDC_0_PD_MASK), -+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_PD, AN7583_MDIO_0_PD_MASK), -+}; -+ - static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), -@@ -1477,6 +2061,62 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK), - }; - -+static const struct airoha_pinctrl_conf an7583_pinctrl_drive_e2_conf[] = { -+ PINCTRL_CONF_DESC(2, REG_GPIO_L_E2, BIT(0)), -+ PINCTRL_CONF_DESC(3, REG_GPIO_L_E2, BIT(1)), -+ PINCTRL_CONF_DESC(4, REG_GPIO_L_E2, BIT(2)), -+ PINCTRL_CONF_DESC(5, REG_GPIO_L_E2, BIT(3)), -+ PINCTRL_CONF_DESC(6, REG_GPIO_L_E2, BIT(4)), -+ PINCTRL_CONF_DESC(7, REG_GPIO_L_E2, BIT(5)), -+ PINCTRL_CONF_DESC(8, REG_GPIO_L_E2, BIT(6)), -+ PINCTRL_CONF_DESC(9, REG_GPIO_L_E2, BIT(7)), -+ PINCTRL_CONF_DESC(10, REG_GPIO_L_E2, BIT(8)), -+ PINCTRL_CONF_DESC(11, REG_GPIO_L_E2, BIT(9)), -+ PINCTRL_CONF_DESC(12, REG_GPIO_L_E2, BIT(10)), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E2, BIT(11)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E2, BIT(12)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E2, BIT(13)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E2, BIT(14)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E2, BIT(15)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E2, BIT(16)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E2, BIT(17)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E2, BIT(18)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E2, BIT(18)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E2, BIT(20)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E2, BIT(21)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E2, BIT(22)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E2, BIT(23)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E2, BIT(24)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E2, BIT(25)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E2, BIT(26)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E2, BIT(27)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E2, BIT(28)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E2, BIT(29)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E2, BIT(30)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E2, BIT(31)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_H_E2, BIT(0)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_H_E2, BIT(1)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_H_E2, BIT(2)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_H_E2, BIT(3)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_H_E2, BIT(4)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_H_E2, BIT(5)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_H_E2, BIT(6)), -+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E2, I2C_SCL_E2_MASK), -+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E2, I2C_SDA_E2_MASK), -+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E2, AN7583_I2C1_SCL_E2_MASK), -+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E2, AN7583_I2C1_SDA_E2_MASK), -+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E2, SPI_CLK_E2_MASK), -+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E2, SPI_CS0_E2_MASK), -+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E2, SPI_MOSI_E2_MASK), -+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E2, SPI_MISO_E2_MASK), -+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E2, UART1_TXD_E2_MASK), -+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E2, UART1_RXD_E2_MASK), -+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E2, PCIE0_RESET_E2_MASK), -+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E2, PCIE1_RESET_E2_MASK), -+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E2, AN7583_MDC_0_E2_MASK), -+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E2, AN7583_MDIO_0_E2_MASK), -+}; -+ - static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = { - PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), - PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), -@@ -1538,12 +2178,73 @@ static const struct airoha_pinctrl_conf - PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK), - }; - -+static const struct airoha_pinctrl_conf an7583_pinctrl_drive_e4_conf[] = { -+ PINCTRL_CONF_DESC(2, REG_GPIO_L_E4, BIT(0)), -+ PINCTRL_CONF_DESC(3, REG_GPIO_L_E4, BIT(1)), -+ PINCTRL_CONF_DESC(4, REG_GPIO_L_E4, BIT(2)), -+ PINCTRL_CONF_DESC(5, REG_GPIO_L_E4, BIT(3)), -+ PINCTRL_CONF_DESC(6, REG_GPIO_L_E4, BIT(4)), -+ PINCTRL_CONF_DESC(7, REG_GPIO_L_E4, BIT(5)), -+ PINCTRL_CONF_DESC(8, REG_GPIO_L_E4, BIT(6)), -+ PINCTRL_CONF_DESC(9, REG_GPIO_L_E4, BIT(7)), -+ PINCTRL_CONF_DESC(10, REG_GPIO_L_E4, BIT(8)), -+ PINCTRL_CONF_DESC(11, REG_GPIO_L_E4, BIT(9)), -+ PINCTRL_CONF_DESC(12, REG_GPIO_L_E4, BIT(10)), -+ PINCTRL_CONF_DESC(13, REG_GPIO_L_E4, BIT(11)), -+ PINCTRL_CONF_DESC(14, REG_GPIO_L_E4, BIT(12)), -+ PINCTRL_CONF_DESC(15, REG_GPIO_L_E4, BIT(13)), -+ PINCTRL_CONF_DESC(16, REG_GPIO_L_E4, BIT(14)), -+ PINCTRL_CONF_DESC(17, REG_GPIO_L_E4, BIT(15)), -+ PINCTRL_CONF_DESC(18, REG_GPIO_L_E4, BIT(16)), -+ PINCTRL_CONF_DESC(19, REG_GPIO_L_E4, BIT(17)), -+ PINCTRL_CONF_DESC(20, REG_GPIO_L_E4, BIT(18)), -+ PINCTRL_CONF_DESC(21, REG_GPIO_L_E4, BIT(18)), -+ PINCTRL_CONF_DESC(22, REG_GPIO_L_E4, BIT(20)), -+ PINCTRL_CONF_DESC(23, REG_GPIO_L_E4, BIT(21)), -+ PINCTRL_CONF_DESC(24, REG_GPIO_L_E4, BIT(22)), -+ PINCTRL_CONF_DESC(25, REG_GPIO_L_E4, BIT(23)), -+ PINCTRL_CONF_DESC(26, REG_GPIO_L_E4, BIT(24)), -+ PINCTRL_CONF_DESC(27, REG_GPIO_L_E4, BIT(25)), -+ PINCTRL_CONF_DESC(28, REG_GPIO_L_E4, BIT(26)), -+ PINCTRL_CONF_DESC(29, REG_GPIO_L_E4, BIT(27)), -+ PINCTRL_CONF_DESC(30, REG_GPIO_L_E4, BIT(28)), -+ PINCTRL_CONF_DESC(31, REG_GPIO_L_E4, BIT(29)), -+ PINCTRL_CONF_DESC(32, REG_GPIO_L_E4, BIT(30)), -+ PINCTRL_CONF_DESC(33, REG_GPIO_L_E4, BIT(31)), -+ PINCTRL_CONF_DESC(34, REG_GPIO_H_E4, BIT(0)), -+ PINCTRL_CONF_DESC(35, REG_GPIO_H_E4, BIT(1)), -+ PINCTRL_CONF_DESC(36, REG_GPIO_H_E4, BIT(2)), -+ PINCTRL_CONF_DESC(37, REG_GPIO_H_E4, BIT(3)), -+ PINCTRL_CONF_DESC(38, REG_GPIO_H_E4, BIT(4)), -+ PINCTRL_CONF_DESC(39, REG_GPIO_H_E4, BIT(5)), -+ PINCTRL_CONF_DESC(40, REG_GPIO_H_E4, BIT(6)), -+ PINCTRL_CONF_DESC(41, REG_I2C_SDA_E4, I2C_SCL_E4_MASK), -+ PINCTRL_CONF_DESC(42, REG_I2C_SDA_E4, I2C_SDA_E4_MASK), -+ PINCTRL_CONF_DESC(43, REG_I2C_SDA_E4, AN7583_I2C1_SCL_E4_MASK), -+ PINCTRL_CONF_DESC(44, REG_I2C_SDA_E4, AN7583_I2C1_SDA_E4_MASK), -+ PINCTRL_CONF_DESC(45, REG_I2C_SDA_E4, SPI_CLK_E4_MASK), -+ PINCTRL_CONF_DESC(46, REG_I2C_SDA_E4, SPI_CS0_E4_MASK), -+ PINCTRL_CONF_DESC(47, REG_I2C_SDA_E4, SPI_MOSI_E4_MASK), -+ PINCTRL_CONF_DESC(48, REG_I2C_SDA_E4, SPI_MISO_E4_MASK), -+ PINCTRL_CONF_DESC(49, REG_I2C_SDA_E4, UART1_TXD_E4_MASK), -+ PINCTRL_CONF_DESC(50, REG_I2C_SDA_E4, UART1_RXD_E4_MASK), -+ PINCTRL_CONF_DESC(51, REG_I2C_SDA_E4, PCIE0_RESET_E4_MASK), -+ PINCTRL_CONF_DESC(52, REG_I2C_SDA_E4, PCIE1_RESET_E4_MASK), -+ PINCTRL_CONF_DESC(53, REG_I2C_SDA_E4, AN7583_MDC_0_E4_MASK), -+ PINCTRL_CONF_DESC(54, REG_I2C_SDA_E4, AN7583_MDIO_0_E4_MASK), -+}; -+ - static const struct airoha_pinctrl_conf en7581_pinctrl_pcie_rst_od_conf[] = { - PINCTRL_CONF_DESC(61, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), - PINCTRL_CONF_DESC(62, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), - PINCTRL_CONF_DESC(63, REG_PCIE_RESET_OD, PCIE2_RESET_OD_MASK), - }; - -+static const struct airoha_pinctrl_conf an7583_pinctrl_pcie_rst_od_conf[] = { -+ PINCTRL_CONF_DESC(51, REG_PCIE_RESET_OD, PCIE0_RESET_OD_MASK), -+ PINCTRL_CONF_DESC(52, REG_PCIE_RESET_OD, PCIE1_RESET_OD_MASK), -+}; -+ - static int airoha_convert_pin_to_reg_offset(struct pinctrl_dev *pctrl_dev, - struct pinctrl_gpio_range *range, - int pin) -@@ -1709,7 +2410,7 @@ static const struct irq_chip airoha_gpio - }; - - static int airoha_pinctrl_add_gpiochip(struct airoha_pinctrl *pinctrl, -- struct platform_device *pdev) -+ struct platform_device *pdev) - { - struct airoha_pinctrl_gpiochip *chip = &pinctrl->gpiochip; - struct gpio_chip *gc = &chip->chip; -@@ -1744,7 +2445,7 @@ static int airoha_pinctrl_add_gpiochip(s - return irq; - - err = devm_request_irq(dev, irq, airoha_irq_handler, IRQF_SHARED, -- dev_name(dev), pinctrl); -+ dev_name(dev), pinctrl); - if (err) { - dev_err(dev, "error requesting irq %d: %d\n", irq, err); - return err; -@@ -1808,8 +2509,8 @@ static int airoha_pinmux_set_mux(struct - } - - static int airoha_pinmux_set_direction(struct pinctrl_dev *pctrl_dev, -- struct pinctrl_gpio_range *range, -- unsigned int p, bool input) -+ struct pinctrl_gpio_range *range, -+ unsigned int p, bool input) - { - struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); - u32 mask, index; -@@ -1899,7 +2600,7 @@ static int airoha_pinctrl_set_conf(struc - - - if (regmap_update_bits(pinctrl->chip_scu, reg->offset, reg->mask, -- val << __ffs(reg->mask))) -+ val << __ffs(reg->mask))) - return -EINVAL; - - return 0; -@@ -2118,8 +2819,8 @@ static int airoha_pinconf_group_get(stru - - for (i = 0; i < pinctrl->grps[group].npins; i++) { - if (airoha_pinconf_get(pctrl_dev, -- pinctrl->grps[group].pins[i], -- config)) -+ pinctrl->grps[group].pins[i], -+ config)) - return -ENOTSUPP; - - if (i && cur_config != *config) -@@ -2280,8 +2981,40 @@ static const struct airoha_pinctrl_match - }, - }; - -+static const struct airoha_pinctrl_match_data an7583_pinctrl_match_data = { -+ .pins = an7583_pinctrl_pins, -+ .num_pins = ARRAY_SIZE(an7583_pinctrl_pins), -+ .grps = an7583_pinctrl_groups, -+ .num_grps = ARRAY_SIZE(an7583_pinctrl_groups), -+ .funcs = an7583_pinctrl_funcs, -+ .num_funcs = ARRAY_SIZE(an7583_pinctrl_funcs), -+ .confs_info = { -+ [AIROHA_PINCTRL_CONFS_PULLUP] = { -+ .confs = an7583_pinctrl_pullup_conf, -+ .num_confs = ARRAY_SIZE(an7583_pinctrl_pullup_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_PULLDOWN] = { -+ .confs = an7583_pinctrl_pulldown_conf, -+ .num_confs = ARRAY_SIZE(an7583_pinctrl_pulldown_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_DRIVE_E2] = { -+ .confs = en7581_pinctrl_drive_e2_conf, -+ .num_confs = ARRAY_SIZE(an7583_pinctrl_drive_e2_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_DRIVE_E4] = { -+ .confs = an7583_pinctrl_drive_e4_conf, -+ .num_confs = ARRAY_SIZE(an7583_pinctrl_drive_e4_conf), -+ }, -+ [AIROHA_PINCTRL_CONFS_PCIE_RST_OD] = { -+ .confs = an7583_pinctrl_pcie_rst_od_conf, -+ .num_confs = ARRAY_SIZE(an7583_pinctrl_pcie_rst_od_conf), -+ }, -+ }, -+}; -+ - static const struct of_device_id airoha_pinctrl_of_match[] = { - { .compatible = "airoha,en7581-pinctrl", .data = &en7581_pinctrl_match_data }, -+ { .compatible = "airoha,an7583-pinctrl", .data = &an7583_pinctrl_match_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, airoha_pinctrl_of_match); diff --git a/target/linux/airoha/patches-6.12/110-v6.19-net-airoha-Do-not-loopback-traffic-to-GDM2-if-it-is-.patch b/target/linux/airoha/patches-6.12/110-v6.19-net-airoha-Do-not-loopback-traffic-to-GDM2-if-it-is-.patch deleted file mode 100644 index 526243eed2c..00000000000 --- a/target/linux/airoha/patches-6.12/110-v6.19-net-airoha-Do-not-loopback-traffic-to-GDM2-if-it-is-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8e0a754b0836d996802713bbebc87bc1cc17925c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 13 Nov 2025 18:19:38 +0100 -Subject: [PATCH] net: airoha: Do not loopback traffic to GDM2 if it is - available on the device - -Airoha_eth driver forwards offloaded uplink traffic (packets received -on GDM1 and forwarded to GDM{3,4}) to GDM2 in order to apply hw QoS. -This is correct if the device does not support a dedicated GDM2 port. -In this case, in order to enable hw offloading for uplink traffic, -the packets should be sent to GDM{3,4} directly. - -Fixes: 9cd451d414f6 ("net: airoha: Add loopback support for GDM2") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251113-airoha-hw-offload-gdm2-fix-v1-1-7e4ca300872f@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -308,7 +308,7 @@ static int airoha_ppe_foe_entry_prepare( - if (!airoha_is_valid_gdm_port(eth, port)) - return -EINVAL; - -- if (dsa_port >= 0) -+ if (dsa_port >= 0 || eth->ports[1]) - pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 - : port->id; - else diff --git a/target/linux/airoha/patches-6.12/111-v6.19-wifi-mt76-Introduce-the-NPU-generic-layer.patch b/target/linux/airoha/patches-6.12/111-v6.19-wifi-mt76-Introduce-the-NPU-generic-layer.patch deleted file mode 100644 index 6225a92b4a8..00000000000 --- a/target/linux/airoha/patches-6.12/111-v6.19-wifi-mt76-Introduce-the-NPU-generic-layer.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 62f1347fa5bf6e6c9c054aedb9e87e7205fa12ac Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Oct 2025 10:50:32 +0200 -Subject: [PATCH] wifi: mt76: Introduce the NPU generic layer - -Add the NPU generic layer in mt76 module. NPU will be used to enable -traffic forward offloading between the MT76 NIC and the Airoha ethernet one -available on the Airoha EN7581 SoC using Netfilter Flowtable APIs. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20251017-mt76-npu-devel-v2-4-ddaa90901723@kernel.org -Signed-off-by: Felix Fietkau ---- - drivers/net/wireless/mediatek/mt76/Kconfig | 4 + - drivers/net/wireless/mediatek/mt76/Makefile | 1 + - drivers/net/wireless/mediatek/mt76/dma.c | 41 +- - drivers/net/wireless/mediatek/mt76/dma.h | 36 ++ - drivers/net/wireless/mediatek/mt76/mac80211.c | 6 +- - drivers/net/wireless/mediatek/mt76/mt76.h | 135 +++++ - drivers/net/wireless/mediatek/mt76/npu.c | 494 ++++++++++++++++++ - include/linux/soc/airoha/airoha_offload.h | 1 + - 8 files changed, 711 insertions(+), 7 deletions(-) - create mode 100644 drivers/net/wireless/mediatek/mt76/npu.c - ---- a/include/linux/soc/airoha/airoha_offload.h -+++ b/include/linux/soc/airoha/airoha_offload.h -@@ -6,6 +6,7 @@ - #ifndef AIROHA_OFFLOAD_H - #define AIROHA_OFFLOAD_H - -+#include - #include - #include - diff --git a/target/linux/airoha/patches-6.12/112-v6.19-pinctrl-airoha-fix-pinctrl-function-mismatch-issue.patch b/target/linux/airoha/patches-6.12/112-v6.19-pinctrl-airoha-fix-pinctrl-function-mismatch-issue.patch deleted file mode 100644 index e55475f81f4..00000000000 --- a/target/linux/airoha/patches-6.12/112-v6.19-pinctrl-airoha-fix-pinctrl-function-mismatch-issue.patch +++ /dev/null @@ -1,38 +0,0 @@ -From f2bd5a0f59d052d16749bccf637690e51947a5d6 Mon Sep 17 00:00:00 2001 -From: Chukun Pan -Date: Sat, 15 Nov 2025 18:00:00 +0800 -Subject: [PATCH] pinctrl: airoha: fix pinctrl function mismatch issue - -The blamed commit made the following changes: - --#define PINCTRL_FUNC_DESC(id)... -- .desc = PINCTRL_PINFUNCTION(#id, ... -+#define PINCTRL_FUNC_DESC(id, table)... -+ .desc = PINCTRL_PINFUNCTION(#id, ... - -- PINCTRL_FUNC_DESC(pon)... -+ PINCTRL_FUNC_DESC("pon", pon)... - -It's clear that the id of funcs doesn't match the definition. -Remove redundant #string from the definition to fix this issue: -pinctrl-airoha ...: invalid function mdio in map table - -Fixes: 4043b0c45f85 ("pinctrl: airoha: generalize pins/group/function/confs handling") -Signed-off-by: Chukun Pan -Acked-by: Christian Marangi -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -35,7 +35,7 @@ - - #define PINCTRL_FUNC_DESC(id, table) \ - { \ -- .desc = PINCTRL_PINFUNCTION(#id, table##_groups, \ -+ .desc = PINCTRL_PINFUNCTION(id, table##_groups, \ - ARRAY_SIZE(table##_groups)),\ - .groups = table##_func_group, \ - .group_size = ARRAY_SIZE(table##_func_group), \ diff --git a/target/linux/airoha/patches-6.12/113-v6.19-pinctrl-airoha-Fix-AIROHA_PINCTRL_CONFS_DRIVE_E2.patch b/target/linux/airoha/patches-6.12/113-v6.19-pinctrl-airoha-Fix-AIROHA_PINCTRL_CONFS_DRIVE_E2.patch deleted file mode 100644 index c4044e3a32a..00000000000 --- a/target/linux/airoha/patches-6.12/113-v6.19-pinctrl-airoha-Fix-AIROHA_PINCTRL_CONFS_DRIVE_E2.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0341d1b1ebf10bcbb9f35e174e83dbb21068387d Mon Sep 17 00:00:00 2001 -From: Nathan Chancellor -Date: Wed, 12 Nov 2025 11:44:30 -0700 -Subject: [PATCH] pinctrl: airoha: Fix AIROHA_PINCTRL_CONFS_DRIVE_E2 in - an7583_pinctrl_match_data - -Clang warns (or errors with CONFIG_WERROR=y / W=e): - - pinctrl/mediatek/pinctrl-airoha.c:2064:41: error: variable 'an7583_pinctrl_drive_e2_conf' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration] - 2064 | static const struct airoha_pinctrl_conf an7583_pinctrl_drive_e2_conf[] = { - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Due to a typo, an7583_pinctrl_drive_e2_conf is only used within -ARRAY_SIZE() (hence no instance of -Wunused-variable), which is -evaluated at compile time, so it will not be needed in the final object -file. - -Fix the .confs assignment for AIROHA_PINCTRL_CONFS_DRIVE_E2 in -an7583_pinctrl_match_data to clear up the warning. - -Closes: https://github.com/ClangBuiltLinux/linux/issues/2142 -Fixes: 3ffeb17a9a27 ("pinctrl: airoha: add support for Airoha AN7583 PINs") -Signed-off-by: Nathan Chancellor -Acked-by: Christian Marangi -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -2998,7 +2998,7 @@ static const struct airoha_pinctrl_match - .num_confs = ARRAY_SIZE(an7583_pinctrl_pulldown_conf), - }, - [AIROHA_PINCTRL_CONFS_DRIVE_E2] = { -- .confs = en7581_pinctrl_drive_e2_conf, -+ .confs = an7583_pinctrl_drive_e2_conf, - .num_confs = ARRAY_SIZE(an7583_pinctrl_drive_e2_conf), - }, - [AIROHA_PINCTRL_CONFS_DRIVE_E4] = { diff --git a/target/linux/airoha/patches-6.12/114-v7.0-hwrng-airoha-set-rng-quality-to-900.patch b/target/linux/airoha/patches-6.12/114-v7.0-hwrng-airoha-set-rng-quality-to-900.patch deleted file mode 100644 index 7df5a18537c..00000000000 --- a/target/linux/airoha/patches-6.12/114-v7.0-hwrng-airoha-set-rng-quality-to-900.patch +++ /dev/null @@ -1,57 +0,0 @@ -From c0008a29a006091d7f9d288620c2456afa23ff27 Mon Sep 17 00:00:00 2001 -From: Aleksander Jan Bajkowski -Date: Mon, 5 Jan 2026 21:41:49 +0100 -Subject: [PATCH] hwrng: airoha - set rng quality to 900 - -Airoha uses RAW mode to collect noise from the TRNG. These appear to -be unprocessed oscillations from the tero loop. For this reason, they -do not have a perfect distribution and entropy. Simple noise compression -reduces its size by 9%, so setting the quality to 900 seems reasonable. -The same value is used by the downstream driver. - -Compare the size before and after compression: -$ ls -l random_airoha* --rw-r--r-- 1 aleksander aleksander 76546048 Jan 3 23:43 random_airoha --rw-rw-r-- 1 aleksander aleksander 69783562 Jan 5 20:23 random_airoha.zip - -FIPS test results: -$ cat random_airoha | rngtest -c 10000 -rngtest 2.6 -Copyright (c) 2004 by Henrique de Moraes Holschuh -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -rngtest: starting FIPS tests... -rngtest: bits received from input: 200000032 -rngtest: FIPS 140-2 successes: 0 -rngtest: FIPS 140-2 failures: 10000 -rngtest: FIPS 140-2(2001-10-10) Monobit: 9957 -rngtest: FIPS 140-2(2001-10-10) Poker: 10000 -rngtest: FIPS 140-2(2001-10-10) Runs: 10000 -rngtest: FIPS 140-2(2001-10-10) Long run: 4249 -rngtest: FIPS 140-2(2001-10-10) Continuous run: 0 -rngtest: input channel speed: (min=953.674; avg=27698.935; max=19073.486)Mibits/s -rngtest: FIPS tests speed: (min=59.791; avg=298.028; max=328.853)Mibits/s -rngtest: Program run time: 647638 microseconds - -In general, these data look like real noise, but with lower entropy -than expected. - -Fixes: e53ca8efcc5e ("hwrng: airoha - add support for Airoha EN7581 TRNG") -Suggested-by: Benjamin Larsson -Signed-off-by: Aleksander Jan Bajkowski -Signed-off-by: Herbert Xu ---- - drivers/char/hw_random/airoha-trng.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/char/hw_random/airoha-trng.c -+++ b/drivers/char/hw_random/airoha-trng.c -@@ -212,6 +212,7 @@ static int airoha_trng_probe(struct plat - trng->rng.init = airoha_trng_init; - trng->rng.cleanup = airoha_trng_cleanup; - trng->rng.read = airoha_trng_read; -+ trng->rng.quality = 900; - - ret = devm_hwrng_register(dev, &trng->rng); - if (ret) { diff --git a/target/linux/airoha/patches-6.12/115-v7.0-net-airoha-Fix-npu-rx-DMA-definitions.patch b/target/linux/airoha/patches-6.12/115-v7.0-net-airoha-Fix-npu-rx-DMA-definitions.patch deleted file mode 100644 index 1d29e5471fd..00000000000 --- a/target/linux/airoha/patches-6.12/115-v7.0-net-airoha-Fix-npu-rx-DMA-definitions.patch +++ /dev/null @@ -1,34 +0,0 @@ -From a7fc8c641cab855824c45e5e8877e40fd528b5df Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 2 Jan 2026 12:29:38 +0100 -Subject: [PATCH] net: airoha: Fix npu rx DMA definitions - -Fix typos in npu rx DMA descriptor definitions. - -Fixes: b3ef7bdec66fb ("net: airoha: Add airoha_offload.h header") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260102-airoha-npu-dma-rx-def-fixes-v1-1-205fc6bf7d94@kernel.org -Signed-off-by: Jakub Kicinski ---- - include/linux/soc/airoha/airoha_offload.h | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/include/linux/soc/airoha/airoha_offload.h -+++ b/include/linux/soc/airoha/airoha_offload.h -@@ -71,12 +71,12 @@ static inline void airoha_ppe_dev_check_ - #define NPU_RX1_DESC_NUM 512 - - /* CTRL */ --#define NPU_RX_DMA_DESC_LAST_MASK BIT(29) --#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(28, 15) --#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(14, 1) -+#define NPU_RX_DMA_DESC_LAST_MASK BIT(27) -+#define NPU_RX_DMA_DESC_LEN_MASK GENMASK(26, 14) -+#define NPU_RX_DMA_DESC_CUR_LEN_MASK GENMASK(13, 1) - #define NPU_RX_DMA_DESC_DONE_MASK BIT(0) - /* INFO */ --#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 28) -+#define NPU_RX_DMA_PKT_COUNT_MASK GENMASK(31, 29) - #define NPU_RX_DMA_PKT_ID_MASK GENMASK(28, 26) - #define NPU_RX_DMA_SRC_PORT_MASK GENMASK(25, 21) - #define NPU_RX_DMA_CRSN_MASK GENMASK(20, 16) diff --git a/target/linux/airoha/patches-6.12/116-v6.19-net-airoha-Move-net_devs-registration-in-a-dedicated.patch b/target/linux/airoha/patches-6.12/116-v6.19-net-airoha-Move-net_devs-registration-in-a-dedicated.patch deleted file mode 100644 index bd445bb71ad..00000000000 --- a/target/linux/airoha/patches-6.12/116-v6.19-net-airoha-Move-net_devs-registration-in-a-dedicated.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 5e7365b5a1ac8f517a7a84442289d7de242deb76 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 14 Dec 2025 10:30:07 +0100 -Subject: [PATCH] net: airoha: Move net_devs registration in a dedicated - routine - -Since airoha_probe() is not executed under rtnl lock, there is small race -where a given device is configured by user-space while the remaining ones -are not completely loaded from the dts yet. This condition will allow a -hw device misconfiguration since there are some conditions (e.g. GDM2 check -in airoha_dev_init()) that require all device are properly loaded from the -device tree. Fix the issue moving net_devices registration at the end of -the airoha_probe routine. - -Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20251214-airoha-fix-dev-registration-v1-1-860e027ad4c6@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 39 ++++++++++++++++-------- - 1 file changed, 26 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2945,19 +2945,26 @@ static int airoha_alloc_gdm_port(struct - port->id = id; - eth->ports[p] = port; - -- err = airoha_metadata_dst_alloc(port); -- if (err) -- return err; -+ return airoha_metadata_dst_alloc(port); -+} - -- err = register_netdev(dev); -- if (err) -- goto free_metadata_dst; -+static int airoha_register_gdm_devices(struct airoha_eth *eth) -+{ -+ int i; - -- return 0; -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *port = eth->ports[i]; -+ int err; -+ -+ if (!port) -+ continue; -+ -+ err = register_netdev(port->dev); -+ if (err) -+ return err; -+ } - --free_metadata_dst: -- airoha_metadata_dst_free(port); -- return err; -+ return 0; - } - - static int airoha_probe(struct platform_device *pdev) -@@ -3048,6 +3055,10 @@ static int airoha_probe(struct platform_ - } - } - -+ err = airoha_register_gdm_devices(eth); -+ if (err) -+ goto error_napi_stop; -+ - return 0; - - error_napi_stop: -@@ -3061,10 +3072,12 @@ error_hw_cleanup: - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; - -- if (port && port->dev->reg_state == NETREG_REGISTERED) { -+ if (!port) -+ continue; -+ -+ if (port->dev->reg_state == NETREG_REGISTERED) - unregister_netdev(port->dev); -- airoha_metadata_dst_free(port); -- } -+ airoha_metadata_dst_free(port); - } - free_netdev(eth->napi_dev); - platform_set_drvdata(pdev, NULL); diff --git a/target/linux/airoha/patches-6.12/117-v7.0-net-airoha-Use-gdm-port-enum-value-whenever-possible.patch b/target/linux/airoha/patches-6.12/117-v7.0-net-airoha-Use-gdm-port-enum-value-whenever-possible.patch deleted file mode 100644 index fe03313dd64..00000000000 --- a/target/linux/airoha/patches-6.12/117-v7.0-net-airoha-Use-gdm-port-enum-value-whenever-possible.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 4d513329b87c1bd0546d9f0288794e244322daa6 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 5 Jan 2026 10:40:47 +0100 -Subject: [PATCH] net: airoha: Use gdm port enum value whenever possible - -Use AIROHA_GDMx_IDX enum value whenever possible. -This patch is just cosmetic changes and does not introduce any logic one. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260105-airoha-use-port-idx-enum-v1-1-503ca5763858@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 40 +++++++++++++----------- - 1 file changed, 21 insertions(+), 19 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -108,11 +108,11 @@ static int airoha_set_vip_for_gdm_port(s - u32 vip_port; - - switch (port->id) { -- case 3: -+ case AIROHA_GDM3_IDX: - /* FIXME: handle XSI_PCIE1_PORT */ - vip_port = XSI_PCIE0_VIP_PORT_MASK; - break; -- case 4: -+ case AIROHA_GDM4_IDX: - /* FIXME: handle XSI_USB_PORT */ - vip_port = XSI_ETH_VIP_PORT_MASK; - break; -@@ -514,8 +514,8 @@ static int airoha_fe_init(struct airoha_ - FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | - FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); - -- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); -- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK); - - airoha_fe_crsn_qsel_init(eth); - -@@ -1711,27 +1711,29 @@ static int airhoha_set_gdm2_loopback(str - /* Forward the traffic to the proper GDM port */ - pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 - : FE_PSE_PORT_GDM4; -- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); -- airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC_MASK); -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), -+ pse_port); -+ airoha_fe_clear(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), -+ GDM_STRIP_CRC_MASK); - - /* Enable GDM2 loopback */ -- airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); -- airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); -+ airoha_fe_wr(eth, REG_GDM_TXCHN_EN(AIROHA_GDM2_IDX), 0xffffffff); -+ airoha_fe_wr(eth, REG_GDM_RXCHN_EN(AIROHA_GDM2_IDX), 0xffff); - - chan = port->id == AIROHA_GDM3_IDX ? airoha_is_7581(eth) ? 4 : 3 : 0; -- airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), -+ airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX), - LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, - FIELD_PREP(LPBK_CHAN_MASK, chan) | - LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK | - LBK_CHAN_MODE_MASK | LPBK_EN_MASK); -- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), -+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(AIROHA_GDM2_IDX), - GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, - FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | - FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU)); - - /* Disable VIP and IFC for GDM2 */ -- airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); -- airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); -+ airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); -+ airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX)); - - /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ - nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; -@@ -1767,8 +1769,8 @@ static int airoha_dev_init(struct net_de - airoha_set_macaddr(port, dev->dev_addr); - - switch (port->id) { -- case 3: -- case 4: -+ case AIROHA_GDM3_IDX: -+ case AIROHA_GDM4_IDX: - /* If GDM2 is active we can't enable loopback */ - if (!eth->ports[1]) { - int err; -@@ -1778,7 +1780,7 @@ static int airoha_dev_init(struct net_de - return err; - } - fallthrough; -- case 2: -+ case AIROHA_GDM2_IDX: - if (airoha_ppe_is_enabled(eth, 1)) { - /* For PPE2 always use secondary cpu port. */ - fe_cpu_port = FE_PSE_PORT_CDM2; -@@ -3121,14 +3123,14 @@ static const char * const en7581_xsi_rst - static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) - { - switch (port->id) { -- case 3: -+ case AIROHA_GDM3_IDX: - /* 7581 SoC supports PCIe serdes on GDM3 port */ - if (nbq == 4) - return HSGMII_LAN_7581_PCIE0_SRCPORT; - if (nbq == 5) - return HSGMII_LAN_7581_PCIE1_SRCPORT; - break; -- case 4: -+ case AIROHA_GDM4_IDX: - /* 7581 SoC supports eth and usb serdes on GDM4 port */ - if (!nbq) - return HSGMII_LAN_7581_ETH_SRCPORT; -@@ -3152,12 +3154,12 @@ static const char * const an7583_xsi_rst - static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq) - { - switch (port->id) { -- case 3: -+ case AIROHA_GDM3_IDX: - /* 7583 SoC supports eth serdes on GDM3 port */ - if (!nbq) - return HSGMII_LAN_7583_ETH_SRCPORT; - break; -- case 4: -+ case AIROHA_GDM4_IDX: - /* 7583 SoC supports PCIe and USB serdes on GDM4 port */ - if (!nbq) - return HSGMII_LAN_7583_PCIE_SRCPORT; diff --git a/target/linux/airoha/patches-6.12/118-v7.0-net-airoha-npu-Dump-fw-version-during-probe.patch b/target/linux/airoha/patches-6.12/118-v7.0-net-airoha-npu-Dump-fw-version-during-probe.patch deleted file mode 100644 index 36f8850c6cd..00000000000 --- a/target/linux/airoha/patches-6.12/118-v7.0-net-airoha-npu-Dump-fw-version-during-probe.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e4bc5dd53bf5d46cd58f081ffccc3809e2be5373 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 5 Jan 2026 09:49:16 +0100 -Subject: [PATCH] net: airoha: npu: Dump fw version during probe - -Dump firmware version running on the npu during module probe. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260105-airoha-npu-dump-fw-v1-1-36d8326975f8@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -658,6 +658,7 @@ static int airoha_npu_probe(struct platf - struct device_node *np; - void __iomem *base; - int i, irq, err; -+ u32 val; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) -@@ -757,6 +758,11 @@ static int airoha_npu_probe(struct platf - regmap_write(npu->regmap, REG_CR_BOOT_TRIGGER, 0x1); - msleep(100); - -+ if (!airoha_npu_wlan_msg_get(npu, 0, WLAN_FUNC_GET_WAIT_NPU_VERSION, -+ &val, sizeof(val), GFP_KERNEL)) -+ dev_info(dev, "NPU fw version: %0d.%d\n", -+ (val >> 16) & 0xffff, val & 0xffff); -+ - platform_set_drvdata(pdev, npu); - - return 0; diff --git a/target/linux/airoha/patches-6.12/119-v6.19-net-airoha-Fix-schedule-while-atomic-in-airoha_ppe_d.patch b/target/linux/airoha/patches-6.12/119-v6.19-net-airoha-Fix-schedule-while-atomic-in-airoha_ppe_d.patch deleted file mode 100644 index 2a7ce09156c..00000000000 --- a/target/linux/airoha/patches-6.12/119-v6.19-net-airoha-Fix-schedule-while-atomic-in-airoha_ppe_d.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 6abcf751bc084804a9e5b3051442e8a2ce67f48a Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 5 Jan 2026 09:43:31 +0100 -Subject: [PATCH] net: airoha: Fix schedule while atomic in airoha_ppe_deinit() - -airoha_ppe_deinit() runs airoha_npu_ppe_deinit() in atomic context. -airoha_npu_ppe_deinit routine allocates ppe_data buffer with GFP_KERNEL -flag. Rely on rcu_replace_pointer in airoha_ppe_deinit routine in order -to fix schedule while atomic issue in airoha_npu_ppe_deinit() since we -do not need atomic context there. - -Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260105-airoha-fw-ethtool-v2-1-3b32b158cc31@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -1547,13 +1547,16 @@ void airoha_ppe_deinit(struct airoha_eth - { - struct airoha_npu *npu; - -- rcu_read_lock(); -- npu = rcu_dereference(eth->npu); -+ mutex_lock(&flow_offload_mutex); -+ -+ npu = rcu_replace_pointer(eth->npu, NULL, -+ lockdep_is_held(&flow_offload_mutex)); - if (npu) { - npu->ops.ppe_deinit(npu); - airoha_npu_put(npu); - } -- rcu_read_unlock(); -+ -+ mutex_unlock(&flow_offload_mutex); - - rhashtable_destroy(ð->ppe->l2_flows); - rhashtable_destroy(ð->flow_table); diff --git a/target/linux/airoha/patches-6.12/120-v7.0-net-airoha-implement-get_link_ksettings.patch b/target/linux/airoha/patches-6.12/120-v7.0-net-airoha-implement-get_link_ksettings.patch deleted file mode 100644 index e08bd168fa0..00000000000 --- a/target/linux/airoha/patches-6.12/120-v7.0-net-airoha-implement-get_link_ksettings.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 50e194b6da721e4fa1fc6ebcf5969803c214929a Mon Sep 17 00:00:00 2001 -From: Aleksander Jan Bajkowski -Date: Sat, 10 Jan 2026 18:02:05 +0100 -Subject: [PATCH] net: airoha: implement get_link_ksettings - -Implement the .get_link_ksettings to get the rate, duplex, and -auto-negotiation status. - -Signed-off-by: Aleksander Jan Bajkowski -Tested-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260110170212.570793-1-olek2@wp.pl -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2826,6 +2826,7 @@ static const struct ethtool_ops airoha_e - .get_drvinfo = airoha_ethtool_get_drvinfo, - .get_eth_mac_stats = airoha_ethtool_get_mac_stats, - .get_rmon_stats = airoha_ethtool_get_rmon_stats, -+ .get_link_ksettings = phy_ethtool_get_link_ksettings, - .get_link = ethtool_op_get_link, - }; - diff --git a/target/linux/airoha/patches-6.12/121-v7.0-net-airoha-npu-Init-BA-memory-region-if-provided-via.patch b/target/linux/airoha/patches-6.12/121-v7.0-net-airoha-npu-Init-BA-memory-region-if-provided-via.patch deleted file mode 100644 index 9283e18de6b..00000000000 --- a/target/linux/airoha/patches-6.12/121-v7.0-net-airoha-npu-Init-BA-memory-region-if-provided-via.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 875a59c9a9e584d99d8e9e5aa8435ec9300bfe91 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 8 Jan 2026 16:05:08 +0100 -Subject: [PATCH] net: airoha: npu: Init BA memory region if provided via DTS - -Initialize NPU Block Ack memory region if reserved via DTS. -Block Ack memory region is used by NPU MT7996 (Eagle) offloading. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260108-airoha-ba-memory-region-v3-2-bf1814e5dcc4@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -519,6 +519,14 @@ static int airoha_npu_wlan_init_memory(s - if (err) - return err; - -+ if (of_property_match_string(npu->dev->of_node, "memory-region-names", -+ "ba") >= 0) { -+ cmd = WLAN_FUNC_SET_WAIT_DRAM_BA_NODE_ADDR; -+ err = airoha_npu_wlan_set_reserved_memory(npu, 0, "ba", cmd); -+ if (err) -+ return err; -+ } -+ - cmd = WLAN_FUNC_SET_WAIT_IS_FORCE_TO_CPU; - return airoha_npu_wlan_msg_send(npu, 0, cmd, &val, sizeof(val), - GFP_KERNEL); diff --git a/target/linux/airoha/patches-6.12/122-v7.0-net-airoha_eth-increase-max-MTU-to-9220-for-DSA-jumb.patch b/target/linux/airoha/patches-6.12/122-v7.0-net-airoha_eth-increase-max-MTU-to-9220-for-DSA-jumb.patch deleted file mode 100644 index ddd02ed2b9d..00000000000 --- a/target/linux/airoha/patches-6.12/122-v7.0-net-airoha_eth-increase-max-MTU-to-9220-for-DSA-jumb.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 6406fc709ace081575de2a8a7eee12e63d4c96c6 Mon Sep 17 00:00:00 2001 -From: Sayantan Nandy -Date: Mon, 19 Jan 2026 13:06:58 +0530 -Subject: [PATCH] net: airoha_eth: increase max MTU to 9220 for DSA jumbo - frames - -The industry standard jumbo frame MTU is 9216 bytes. When using the DSA -subsystem, a 4-byte tag is added to each Ethernet frame. - -Increase AIROHA_MAX_MTU to 9220 bytes (9216 + 4) so that users can set a -standard 9216-byte MTU on DSA ports. - -The underlying hardware supports significantly larger frame sizes -(approximately 16K). However, the maximum MTU is limited to 9220 bytes -for now, as this is sufficient to support standard jumbo frames and does -not incur additional memory allocation overhead. - -Signed-off-by: Sayantan Nandy -Reviewed-by: Andrew Lunn -Acked-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260119073658.6216-1-sayantann11@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -21,7 +21,7 @@ - #define AIROHA_MAX_NUM_IRQ_BANKS 4 - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 --#define AIROHA_MAX_MTU 9216 -+#define AIROHA_MAX_MTU 9220 - #define AIROHA_MAX_PACKET_SIZE 2048 - #define AIROHA_NUM_QOS_CHANNELS 4 - #define AIROHA_NUM_QOS_QUEUES 8 diff --git a/target/linux/airoha/patches-6.12/123-v7.0-net-airoha-npu-Add-the-capability-to-read-firmware-n.patch b/target/linux/airoha/patches-6.12/123-v7.0-net-airoha-npu-Add-the-capability-to-read-firmware-n.patch deleted file mode 100644 index 35ad950f420..00000000000 --- a/target/linux/airoha/patches-6.12/123-v7.0-net-airoha-npu-Add-the-capability-to-read-firmware-n.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 3847173525e307ebcd23bd4863da943ea78b0057 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 20 Jan 2026 11:17:18 +0100 -Subject: [PATCH] net: airoha: npu: Add the capability to read firmware names - from dts - -Introduce the capability to read the firmware binary names from device-tree -using the firmware-name property if available. -This patch is needed because NPU firmware binaries are board specific since -they depend on the MediaTek WiFi chip used on the board (e.g. MT7996 or -MT7992) and the WiFi chip version info is not available in the NPU driver. -This is a preliminary patch to enable MT76 NPU offloading if the Airoha SoC -is equipped with MT7996 (Eagle) WiFi chipset. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20260120-airoha-npu-firmware-name-v4-2-88999628b4c1@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_npu.c | 46 ++++++++++++++++++++---- - 1 file changed, 40 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_npu.c -+++ b/drivers/net/ethernet/airoha/airoha_npu.c -@@ -16,6 +16,8 @@ - - #define NPU_EN7581_FIRMWARE_DATA "airoha/en7581_npu_data.bin" - #define NPU_EN7581_FIRMWARE_RV32 "airoha/en7581_npu_rv32.bin" -+#define NPU_EN7581_7996_FIRMWARE_DATA "airoha/en7581_MT7996_npu_data.bin" -+#define NPU_EN7581_7996_FIRMWARE_RV32 "airoha/en7581_MT7996_npu_rv32.bin" - #define NPU_AN7583_FIRMWARE_DATA "airoha/an7583_npu_data.bin" - #define NPU_AN7583_FIRMWARE_RV32 "airoha/an7583_npu_rv32.bin" - #define NPU_EN7581_FIRMWARE_RV32_MAX_SIZE 0x200000 -@@ -195,18 +197,18 @@ static int airoha_npu_send_msg(struct ai - } - - static int airoha_npu_load_firmware(struct device *dev, void __iomem *addr, -- const struct airoha_npu_fw *fw_info) -+ const char *fw_name, int fw_max_size) - { - const struct firmware *fw; - int ret; - -- ret = request_firmware(&fw, fw_info->name, dev); -+ ret = request_firmware(&fw, fw_name, dev); - if (ret) - return ret == -ENOENT ? -EPROBE_DEFER : ret; - -- if (fw->size > fw_info->max_size) { -+ if (fw->size > fw_max_size) { - dev_err(dev, "%s: fw size too overlimit (%zu)\n", -- fw_info->name, fw->size); -+ fw_name, fw->size); - ret = -E2BIG; - goto out; - } -@@ -218,6 +220,28 @@ out: - return ret; - } - -+static int -+airoha_npu_load_firmware_from_dts(struct device *dev, void __iomem *addr, -+ void __iomem *base) -+{ -+ const char *fw_names[2]; -+ int ret; -+ -+ ret = of_property_read_string_array(dev->of_node, "firmware-name", -+ fw_names, ARRAY_SIZE(fw_names)); -+ if (ret != ARRAY_SIZE(fw_names)) -+ return -EINVAL; -+ -+ ret = airoha_npu_load_firmware(dev, addr, fw_names[0], -+ NPU_EN7581_FIRMWARE_RV32_MAX_SIZE); -+ if (ret) -+ return ret; -+ -+ return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, -+ fw_names[1], -+ NPU_EN7581_FIRMWARE_DATA_MAX_SIZE); -+} -+ - static int airoha_npu_run_firmware(struct device *dev, void __iomem *base, - struct reserved_mem *rmem) - { -@@ -233,14 +257,22 @@ static int airoha_npu_run_firmware(struc - if (IS_ERR(addr)) - return PTR_ERR(addr); - -+ /* Try to load firmware images using the firmware names provided via -+ * dts if available. -+ */ -+ if (of_find_property(dev->of_node, "firmware-name", NULL)) -+ return airoha_npu_load_firmware_from_dts(dev, addr, base); -+ - /* Load rv32 npu firmware */ -- ret = airoha_npu_load_firmware(dev, addr, &soc->fw_rv32); -+ ret = airoha_npu_load_firmware(dev, addr, soc->fw_rv32.name, -+ soc->fw_rv32.max_size); - if (ret) - return ret; - - /* Load data npu firmware */ - return airoha_npu_load_firmware(dev, base + REG_NPU_LOCAL_SRAM, -- &soc->fw_data); -+ soc->fw_data.name, -+ soc->fw_data.max_size); - } - - static irqreturn_t airoha_npu_mbox_handler(int irq, void *npu_instance) -@@ -797,6 +829,8 @@ module_platform_driver(airoha_npu_driver - - MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); - MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); -+MODULE_FIRMWARE(NPU_EN7581_7996_FIRMWARE_DATA); -+MODULE_FIRMWARE(NPU_EN7581_7996_FIRMWARE_RV32); - MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_DATA); - MODULE_FIRMWARE(NPU_AN7583_FIRMWARE_RV32); - MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/124-v7.1-net-airoha-fix-typo-in-function-name.patch b/target/linux/airoha/patches-6.12/124-v7.1-net-airoha-fix-typo-in-function-name.patch deleted file mode 100644 index 72644140b8d..00000000000 --- a/target/linux/airoha/patches-6.12/124-v7.1-net-airoha-fix-typo-in-function-name.patch +++ /dev/null @@ -1,53 +0,0 @@ -From aebf15e8eb09b01e99f043e9f5d423798aac9d32 Mon Sep 17 00:00:00 2001 -From: Zhengping Zhang -Date: Thu, 26 Feb 2026 10:37:08 +0800 -Subject: [PATCH] net: airoha: fix typo in function name - -Corrected the typo in the function name from - `airhoa_is_lan_gdm_port` to `airoha_is_lan_gdm_port`. This change ensures - consistency in the API naming convention. - -Signed-off-by: Zhengping Zhang -Reviewed-by: Simon Horman -Acked-by: Lorenzo Bianconi -Link: https://patch.msgid.link/tencent_E4FD5D6BC0131E617D848896F5F9FCED6E0A@qq.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 2 +- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -76,7 +76,7 @@ static void airoha_set_macaddr(struct ai - struct airoha_eth *eth = port->qdma->eth; - u32 val, reg; - -- reg = airhoa_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H -+ reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H - : REG_FE_WAN_MAC_H; - val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; - airoha_fe_wr(eth, reg, val); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -626,7 +626,7 @@ u32 airoha_rmw(void __iomem *base, u32 o - #define airoha_qdma_clear(qdma, offset, val) \ - airoha_rmw((qdma)->regs, (offset), (val), 0) - --static inline bool airhoa_is_lan_gdm_port(struct airoha_gdm_port *port) -+static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port) - { - /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. - * GDM{2,3,4} can be used as wan port connected to an external ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -321,7 +321,7 @@ static int airoha_ppe_foe_entry_prepare( - /* For downlink traffic consume SRAM memory for hw - * forwarding descriptors queue. - */ -- if (airhoa_is_lan_gdm_port(port)) -+ if (airoha_is_lan_gdm_port(port)) - val |= AIROHA_FOE_IB2_FAST_PATH; - if (dsa_port >= 0) - val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, diff --git a/target/linux/airoha/patches-6.12/125-v7.1-net-airoha-Rely-__field_prep-for-non-constant-masks.patch b/target/linux/airoha/patches-6.12/125-v7.1-net-airoha-Rely-__field_prep-for-non-constant-masks.patch deleted file mode 100644 index 78dc75eb0a8..00000000000 --- a/target/linux/airoha/patches-6.12/125-v7.1-net-airoha-Rely-__field_prep-for-non-constant-masks.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 7600fb3b41dd6ab65ed61169df1b6099044edf97 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 4 Mar 2026 11:56:47 +0100 -Subject: [PATCH] net: airoha: Rely __field_prep for non-constant masks - -Rely on __field_prep macros for non-constant masks preparing the values -for register updates instead of open-coding. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260304-airoha-__field_prep-v1-1-b185facc4e2f@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1748,7 +1748,7 @@ static int airhoha_set_gdm2_loopback(str - airoha_fe_rmw(eth, - REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)), - SP_CPORT_MASK(val), -- FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); -+ __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2)); - - if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth)) - airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, -@@ -1802,7 +1802,7 @@ static int airoha_dev_init(struct net_de - ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0; - airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), - DFT_CPORT_MASK(port->id), -- fe_cpu_port << __ffs(DFT_CPORT_MASK(port->id))); -+ __field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port)); - - return 0; - } -@@ -2159,7 +2159,7 @@ static int airoha_qdma_set_chan_tx_sched - - airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), - CHAN_QOS_MODE_MASK(channel), -- mode << __ffs(CHAN_QOS_MODE_MASK(channel))); -+ __field_prep(CHAN_QOS_MODE_MASK(channel), mode)); - - return 0; - } diff --git a/target/linux/airoha/patches-6.12/126-v7.1-net-airoha-Make-flow-control-source-port-mapping-dep.patch b/target/linux/airoha/patches-6.12/126-v7.1-net-airoha-Make-flow-control-source-port-mapping-dep.patch deleted file mode 100644 index 9e4684bddc9..00000000000 --- a/target/linux/airoha/patches-6.12/126-v7.1-net-airoha-Make-flow-control-source-port-mapping-dep.patch +++ /dev/null @@ -1,52 +0,0 @@ -From bf3471e6e6c02137dc0d26caa783ac1849f9aab8 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 6 Mar 2026 09:07:27 +0100 -Subject: [PATCH] net: airoha: Make flow control source port mapping dependent - on nbq parameter - -Flow control source port mapping for USB serdes needs to be configured -according to the GDM port nbq parameter. This is a preliminary patch -since nbq parameter is specific for the given port serdes and needs to -be read from the DTS (in the current codebase is assigned statically). - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260306-airoha-fix-loopback-for-usb-serdes-v2-1-319de9c96826@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 10 ++++++---- - drivers/net/ethernet/airoha/airoha_regs.h | 5 +---- - 2 files changed, 7 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1750,10 +1750,12 @@ static int airhoha_set_gdm2_loopback(str - SP_CPORT_MASK(val), - __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2)); - -- if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth)) -- airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, -- FC_ID_OF_SRC_PORT24_MASK, -- FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); -+ if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) { -+ u32 mask = FC_ID_OF_SRC_PORT_MASK(nbq); -+ -+ airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask, -+ __field_prep(mask, AIROHA_GDM2_IDX)); -+ } - - return 0; - } ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -376,10 +376,7 @@ - #define SP_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) - - #define REG_SRC_PORT_FC_MAP6 0x2298 --#define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) --#define FC_ID_OF_SRC_PORT26_MASK GENMASK(20, 16) --#define FC_ID_OF_SRC_PORT25_MASK GENMASK(12, 8) --#define FC_ID_OF_SRC_PORT24_MASK GENMASK(4, 0) -+#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3)) - - #define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 - diff --git a/target/linux/airoha/patches-6.12/127-v7.1-net-airoha-Move-GDM-forward-port-configuration-in-nd.patch b/target/linux/airoha/patches-6.12/127-v7.1-net-airoha-Move-GDM-forward-port-configuration-in-nd.patch deleted file mode 100644 index d2458a9aa5d..00000000000 --- a/target/linux/airoha/patches-6.12/127-v7.1-net-airoha-Move-GDM-forward-port-configuration-in-nd.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 46097d011f77f5758fb47b7059b4f1f2e7403940 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 6 Mar 2026 16:09:47 +0100 -Subject: [PATCH] net: airoha: Move GDM forward port configuration in - ndo_open/ndo_stop callbacks - -This change allows to set GDM forward port configuration to -FE_PSE_PORT_DROP stopping the network device. Hw design requires to stop -packet forwarding putting the interface down. Moreover, PPE firmware -requires to use PPE1 for GDM3 or GDM4. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260306-airoha-gdm-forward-ndo-open-stop-v1-1-7b7a20dd9ef0@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 20 +++++++++++++++----- - 1 file changed, 15 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1632,6 +1632,7 @@ static int airoha_dev_open(struct net_de - int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN; - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_qdma *qdma = port->qdma; -+ u32 pse_port = FE_PSE_PORT_PPE1; - - netif_tx_start_all_queues(dev); - err = airoha_set_vip_for_gdm_port(port, true); -@@ -1655,6 +1656,14 @@ static int airoha_dev_open(struct net_de - GLOBAL_CFG_RX_DMA_EN_MASK); - atomic_inc(&qdma->users); - -+ if (port->id == AIROHA_GDM2_IDX && -+ airoha_ppe_is_enabled(qdma->eth, 1)) { -+ /* For PPE2 always use secondary cpu port. */ -+ pse_port = FE_PSE_PORT_PPE2; -+ } -+ airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id), -+ pse_port); -+ - return 0; - } - -@@ -1672,6 +1681,9 @@ static int airoha_dev_stop(struct net_de - for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) - netdev_tx_reset_subqueue(dev, i); - -+ airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id), -+ FE_PSE_PORT_DROP); -+ - if (atomic_dec_and_test(&qdma->users)) { - airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, - GLOBAL_CFG_TX_DMA_EN_MASK | -@@ -1765,7 +1777,7 @@ static int airoha_dev_init(struct net_de - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_qdma *qdma = port->qdma; - struct airoha_eth *eth = qdma->eth; -- u32 pse_port, fe_cpu_port; -+ u32 fe_cpu_port; - u8 ppe_id; - - airoha_set_macaddr(port, dev->dev_addr); -@@ -1786,7 +1798,7 @@ static int airoha_dev_init(struct net_de - if (airoha_ppe_is_enabled(eth, 1)) { - /* For PPE2 always use secondary cpu port. */ - fe_cpu_port = FE_PSE_PORT_CDM2; -- pse_port = FE_PSE_PORT_PPE2; -+ ppe_id = 1; - break; - } - fallthrough; -@@ -1795,13 +1807,11 @@ static int airoha_dev_init(struct net_de - - /* For PPE1 select cpu port according to the running QDMA. */ - fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; -- pse_port = FE_PSE_PORT_PPE1; -+ ppe_id = 0; - break; - } - } - -- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port); -- ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0; - airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), - DFT_CPORT_MASK(port->id), - __field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port)); diff --git a/target/linux/airoha/patches-6.12/129-v7.1-net-airoha-select-QDMA-block-according-LAN-WAN-confi.patch b/target/linux/airoha/patches-6.12/129-v7.1-net-airoha-select-QDMA-block-according-LAN-WAN-confi.patch deleted file mode 100644 index e0eecea69a1..00000000000 --- a/target/linux/airoha/patches-6.12/129-v7.1-net-airoha-select-QDMA-block-according-LAN-WAN-confi.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 8737d7194d6d5947c3d7d8813895b44a25b84477 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 13 Mar 2026 17:28:36 +0100 -Subject: [PATCH] net: airoha: select QDMA block according LAN/WAN - configuration - -Before this patch even GDM ports were assigned to QDMA0 while odd GDM -ports were using QDMA1, so, based on the DTS configuration, both QDMA0 -and QDMA1 can theoretically receive traffic destinated to the host cpu -from LAN or WAN GDM ports. -Airoha folks reported the hw design assumes the LAN traffic destinated -to the host cpu is be forwarded to QDMA0 while traffic received on WAN -GDM port is managed by QDMA1. For this reason, select QDMA block according -to the GDM port LAN or WAN configuration: -- QDMA0 is used for GDM LAN devices -- QDMA1 is used for GDM WAN device - -Assuming a device with three GDM ports, a typical configuration could be: -- MT7530 DSA switch -> GDM1 (eth0) -> QDMA0 (LAN traffic) -- External PHY -> GDM2 (eth1) -> QDMA1 (WAN traffic) -- External PHY -> GDM3 (eth2) -> QDMA0 (LAN traffic) - -We can then bridge eth0 DSA port (lanX) with eth2 since they all tx/rx -LAN traffic. - -Please note this patch introduces a change not visible to the user since -airoha_eth driver currently supports just the internal phy available via -the MT7530 DSA switch and there are no WAN interfaces officially supported -since PCS/external phy is not merged mainline yet (it will be posted with -following patches). - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260313-airoha-qdma-lan-wan-mode-v2-1-7d577db6e40c@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 18 ++++++++---------- - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - 2 files changed, 9 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1775,11 +1775,13 @@ static int airhoha_set_gdm2_loopback(str - static int airoha_dev_init(struct net_device *dev) - { - struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_qdma *qdma = port->qdma; -- struct airoha_eth *eth = qdma->eth; -+ struct airoha_eth *eth = port->eth; - u32 fe_cpu_port; - u8 ppe_id; - -+ /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ -+ port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; -+ port->dev->irq = port->qdma->irq_banks[0].irq; - airoha_set_macaddr(port, dev->dev_addr); - - switch (port->id) { -@@ -1803,7 +1805,7 @@ static int airoha_dev_init(struct net_de - } - fallthrough; - default: { -- u8 qdma_id = qdma - ð->qdma[0]; -+ u8 qdma_id = port->qdma - ð->qdma[0]; - - /* For PPE1 select cpu port according to the running QDMA. */ - fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; -@@ -2887,11 +2889,10 @@ bool airoha_is_valid_gdm_port(struct air - } - - static int airoha_alloc_gdm_port(struct airoha_eth *eth, -- struct device_node *np, int index) -+ struct device_node *np) - { - const __be32 *id_ptr = of_get_property(np, "reg", NULL); - struct airoha_gdm_port *port; -- struct airoha_qdma *qdma; - struct net_device *dev; - int err, p; - u32 id; -@@ -2922,7 +2923,6 @@ static int airoha_alloc_gdm_port(struct - return -ENOMEM; - } - -- qdma = ð->qdma[index % AIROHA_MAX_NUM_QDMA]; - dev->netdev_ops = &airoha_netdev_ops; - dev->ethtool_ops = &airoha_ethtool_ops; - dev->max_mtu = AIROHA_MAX_MTU; -@@ -2934,7 +2934,6 @@ static int airoha_alloc_gdm_port(struct - dev->features |= dev->hw_features; - dev->vlan_features = dev->hw_features; - dev->dev.of_node = np; -- dev->irq = qdma->irq_banks[0].irq; - SET_NETDEV_DEV(dev, eth->dev); - - /* reserve hw queues for HTB offloading */ -@@ -2955,7 +2954,7 @@ static int airoha_alloc_gdm_port(struct - port = netdev_priv(dev); - u64_stats_init(&port->stats.syncp); - spin_lock_init(&port->stats.lock); -- port->qdma = qdma; -+ port->eth = eth; - port->dev = dev; - port->id = id; - eth->ports[p] = port; -@@ -3055,7 +3054,6 @@ static int airoha_probe(struct platform_ - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) - airoha_qdma_start_napi(ð->qdma[i]); - -- i = 0; - for_each_child_of_node(pdev->dev.of_node, np) { - if (!of_device_is_compatible(np, "airoha,eth-mac")) - continue; -@@ -3063,7 +3061,7 @@ static int airoha_probe(struct platform_ - if (!of_device_is_available(np)) - continue; - -- err = airoha_alloc_gdm_port(eth, np, i++); -+ err = airoha_alloc_gdm_port(eth, np); - if (err) { - of_node_put(np); - goto error_napi_stop; ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -533,6 +533,7 @@ struct airoha_qdma { - - struct airoha_gdm_port { - struct airoha_qdma *qdma; -+ struct airoha_eth *eth; - struct net_device *dev; - int id; - diff --git a/target/linux/airoha/patches-6.12/130-v7.0-net-airoha-Fix-typo-in-airoha_ppe_setup_tc_block_cb-.patch b/target/linux/airoha/patches-6.12/130-v7.0-net-airoha-Fix-typo-in-airoha_ppe_setup_tc_block_cb-.patch deleted file mode 100644 index 9620d1ecd49..00000000000 --- a/target/linux/airoha/patches-6.12/130-v7.0-net-airoha-Fix-typo-in-airoha_ppe_setup_tc_block_cb-.patch +++ /dev/null @@ -1,32 +0,0 @@ -From dfdf774656205515b2d6ad94fce63c7ccbe92d91 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 9 Jan 2026 10:29:06 +0100 -Subject: [PATCH] net: airoha: Fix typo in airoha_ppe_setup_tc_block_cb - definition - -Fix Typo in airoha_ppe_dev_setup_tc_block_cb routine definition when -CONFIG_NET_AIROHA is not enabled. - -Reported-by: kernel test robot -Closes: https://lore.kernel.org/oe-kbuild-all/202601090517.Fj6v501r-lkp@intel.com/ -Fixes: f45fc18b6de04 ("net: airoha: Add airoha_ppe_dev struct definition") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260109-airoha_ppe_dev_setup_tc_block_cb-typo-v1-1-282e8834a9f9@kernel.org -Signed-off-by: Jakub Kicinski ---- - include/linux/soc/airoha/airoha_offload.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/include/linux/soc/airoha/airoha_offload.h -+++ b/include/linux/soc/airoha/airoha_offload.h -@@ -52,8 +52,8 @@ static inline void airoha_ppe_put_dev(st - { - } - --static inline int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, -- void *type_data) -+static inline int airoha_ppe_dev_setup_tc_block_cb(struct airoha_ppe_dev *dev, -+ void *type_data) - { - return -EOPNOTSUPP; - } diff --git a/target/linux/airoha/patches-6.12/131-v7.0-net-phy-mediatek-enable-interrupts-on-AN7581.patch b/target/linux/airoha/patches-6.12/131-v7.0-net-phy-mediatek-enable-interrupts-on-AN7581.patch deleted file mode 100644 index a30014bec56..00000000000 --- a/target/linux/airoha/patches-6.12/131-v7.0-net-phy-mediatek-enable-interrupts-on-AN7581.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 2e229771543b2b20e1fe29da00df80c917469449 Mon Sep 17 00:00:00 2001 -From: Aleksander Jan Bajkowski -Date: Fri, 2 Jan 2026 12:30:06 +0100 -Subject: [PATCH] net: phy: mediatek: enable interrupts on AN7581 - -Interrupts work just like on MT7988. - -Suggested-by: Benjamin Larsson -Signed-off-by: Aleksander Jan Bajkowski -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20260102113222.3519900-1-olek2@wp.pl -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -1492,6 +1492,8 @@ static struct phy_driver mtk_socphy_driv - { - PHY_ID_MATCH_EXACT(MTK_GPHY_ID_AN7581), - .name = "Airoha AN7581 PHY", -+ .config_intr = genphy_no_config_intr, -+ .handle_interrupt = genphy_handle_interrupt_no_ack, - .probe = an7581_phy_probe, - .led_blink_set = mt798x_phy_led_blink_set, - .led_brightness_set = mt798x_phy_led_brightness_set, diff --git a/target/linux/airoha/patches-6.12/132-v7.1-net-airoha-Reset-PPE-default-cput-port-in-airoha_ppe.patch b/target/linux/airoha/patches-6.12/132-v7.1-net-airoha-Reset-PPE-default-cput-port-in-airoha_ppe.patch deleted file mode 100644 index 136c707f7f9..00000000000 --- a/target/linux/airoha/patches-6.12/132-v7.1-net-airoha-Reset-PPE-default-cput-port-in-airoha_ppe.patch +++ /dev/null @@ -1,162 +0,0 @@ -From df8e1e4a2eb5f8ecdef36c502601e8afbc6ad891 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 24 Dec 2025 17:29:33 +0100 -Subject: [PATCH] net: airoha: Reset PPE default cput port in - airoha_ppe_hw_init() - -Before this patch the default PPE cpu port used for a specific GDM -device was set running ndo_init() callback during device initialization. -The selected PPE cpu port configured for the specific GDM device depends -on the QDMA block assigned to the GDM device. The selected QDMA block -depends on LAN/WAN configuration as specified in commmit XXXX. -However, the user selected PPE cpu port can be different with respect to -the one hardcoded in the NPU firmware binary. The hardcoded PPE cput port -value is loaded initializing the PPE engine running npu ops ppe_init() -callback in airoha_ppe_offload_setup routine. -Reset the default value for PPE cpu ports in airoha_ppe_hw_init routine -in order to apply the user requested configuration according to the device -DTS setup. -Please note this patch is fixing an issue not visible to the user (so we -do not need to backport it) since airoha_eth driver currently supports just -the internal phy available via the MT7530 DSA switch and there are no WAN -interfaces officially supporte since PCS/external phy is not merged mainline -yet (it will be posted with following patches). - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 28 +++++------------------ - drivers/net/ethernet/airoha/airoha_eth.h | 2 ++ - drivers/net/ethernet/airoha/airoha_ppe.c | 23 ++++++++++++++++++- - drivers/net/ethernet/airoha/airoha_regs.h | 7 +++--- - 4 files changed, 33 insertions(+), 27 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1776,8 +1776,7 @@ static int airoha_dev_init(struct net_de - { - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_eth *eth = port->eth; -- u32 fe_cpu_port; -- u8 ppe_id; -+ int i; - - /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ - port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; -@@ -1795,28 +1794,13 @@ static int airoha_dev_init(struct net_de - if (err) - return err; - } -- fallthrough; -- case AIROHA_GDM2_IDX: -- if (airoha_ppe_is_enabled(eth, 1)) { -- /* For PPE2 always use secondary cpu port. */ -- fe_cpu_port = FE_PSE_PORT_CDM2; -- ppe_id = 1; -- break; -- } -- fallthrough; -- default: { -- u8 qdma_id = port->qdma - ð->qdma[0]; -- -- /* For PPE1 select cpu port according to the running QDMA. */ -- fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; -- ppe_id = 0; - break; -- } -+ default: -+ break; - } - -- airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id), -- DFT_CPORT_MASK(port->id), -- __field_prep(DFT_CPORT_MASK(port->id), fe_cpu_port)); -+ for (i = 0; i < eth->soc->num_ppe; i++) -+ airoha_ppe_set_cpu_port(port, i); - - return 0; - } -@@ -1919,7 +1903,7 @@ static u32 airoha_get_dsa_tag(struct sk_ - #endif - } - --static int airoha_get_fe_port(struct airoha_gdm_port *port) -+int airoha_get_fe_port(struct airoha_gdm_port *port) - { - struct airoha_qdma *qdma = port->qdma; - struct airoha_eth *eth = qdma->eth; ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -646,9 +646,11 @@ static inline bool airoha_is_7583(struct - return eth->soc->version == 0x7583; - } - -+int airoha_get_fe_port(struct airoha_gdm_port *port); - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - -+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id); - bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); - void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, - u16 hash, bool rx_wlan); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -85,6 +85,20 @@ static u32 airoha_ppe_get_timestamp(stru - return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); - } - -+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id) -+{ -+ struct airoha_qdma *qdma = port->qdma; -+ u8 fport = airoha_get_fe_port(port); -+ struct airoha_eth *eth = qdma->eth; -+ u8 qdma_id = qdma - ð->qdma[0]; -+ u32 fe_cpu_port; -+ -+ fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1; -+ airoha_fe_rmw(eth, REG_PPE_DFT_CPORT(ppe_id, fport), -+ DFT_CPORT_MASK(fport), -+ __field_prep(DFT_CPORT_MASK(fport), fe_cpu_port)); -+} -+ - static void airoha_ppe_hw_init(struct airoha_ppe *ppe) - { - u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries; -@@ -147,7 +161,9 @@ static void airoha_ppe_hw_init(struct ai - - airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); - -- for (p = 0; p < ARRAY_SIZE(eth->ports); p++) -+ for (p = 0; p < ARRAY_SIZE(eth->ports); p++) { -+ struct airoha_gdm_port *port = eth->ports[p]; -+ - airoha_fe_rmw(eth, REG_PPE_MTU(i, p), - FP0_EGRESS_MTU_MASK | - FP1_EGRESS_MTU_MASK, -@@ -155,6 +171,11 @@ static void airoha_ppe_hw_init(struct ai - AIROHA_MAX_MTU) | - FIELD_PREP(FP1_EGRESS_MTU_MASK, - AIROHA_MAX_MTU)); -+ if (!port) -+ continue; -+ -+ airoha_ppe_set_cpu_port(port, i); -+ } - } - } - ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -312,10 +312,9 @@ - #define REG_PPE_HASH_SEED(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x244) - #define PPE_HASH_SEED 0x12345678 - --#define REG_PPE_DFT_CPORT0(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) --#define DFT_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) -- --#define REG_PPE_DFT_CPORT1(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x24c) -+#define REG_PPE_DFT_CPORT_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x248) -+#define REG_PPE_DFT_CPORT(_m, _n) (REG_PPE_DFT_CPORT_BASE(_m) + (((_n) / 8) << 2)) -+#define DFT_CPORT_MASK(_n) GENMASK(3 + (((_n) % 8) << 2), (((_n) % 8) << 2)) - - #define REG_PPE_TB_HASH_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x250) - #define PPE_DRAM_HASH1_MODE_MASK GENMASK(31, 28) diff --git a/target/linux/airoha/patches-6.12/133-v7.1-net-airoha-Rework-the-code-flow-in-airoha_remove-and.patch b/target/linux/airoha/patches-6.12/133-v7.1-net-airoha-Rework-the-code-flow-in-airoha_remove-and.patch deleted file mode 100644 index 37347c6af51..00000000000 --- a/target/linux/airoha/patches-6.12/133-v7.1-net-airoha-Rework-the-code-flow-in-airoha_remove-and.patch +++ /dev/null @@ -1,165 +0,0 @@ -From b1c803d5c8167026791abfaed96fd3e6a1fcd750 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 21 Mar 2026 15:41:44 +0100 -Subject: [PATCH] net: airoha: Rework the code flow in airoha_remove() and in - airoha_probe() error path - -As suggested by Simon in [0], rework the code flow in airoha_remove() -and in the airoha_probe() error path in order to rely on a more common -approach un-registering configured net-devices first and destroying the -hw resources at the end of the code. -Introduce airoha_qdma_cleanup routine to release QDMA resources. - -[0] https://lore.kernel.org/netdev/20251214-airoha-fix-dev-registration-v1-1-860e027ad4c6@kernel.org/ - -Suggested-by: Simon Horman -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20260321-airoha-remove-rework-v2-1-16c7bade5fe5@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 76 ++++++++++++++---------- - 1 file changed, 44 insertions(+), 32 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1389,6 +1389,33 @@ static int airoha_qdma_init(struct platf - return airoha_qdma_hw_init(qdma); - } - -+static void airoha_qdma_cleanup(struct airoha_qdma *qdma) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ if (!qdma->q_rx[i].ndesc) -+ continue; -+ -+ netif_napi_del(&qdma->q_rx[i].napi); -+ airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); -+ if (qdma->q_rx[i].page_pool) { -+ page_pool_destroy(qdma->q_rx[i].page_pool); -+ qdma->q_rx[i].page_pool = NULL; -+ } -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -+ netif_napi_del(&qdma->q_tx_irq[i].napi); -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -+ if (!qdma->q_tx[i].ndesc) -+ continue; -+ -+ airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -+ } -+} -+ - static int airoha_hw_init(struct platform_device *pdev, - struct airoha_eth *eth) - { -@@ -1416,41 +1443,30 @@ static int airoha_hw_init(struct platfor - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { - err = airoha_qdma_init(pdev, eth, ð->qdma[i]); - if (err) -- return err; -+ goto error; - } - - err = airoha_ppe_init(eth); - if (err) -- return err; -+ goto error; - - set_bit(DEV_STATE_INITIALIZED, ð->state); - - return 0; -+error: -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -+ airoha_qdma_cleanup(ð->qdma[i]); -+ -+ return err; - } - --static void airoha_hw_cleanup(struct airoha_qdma *qdma) -+static void airoha_hw_cleanup(struct airoha_eth *eth) - { - int i; - -- for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -- if (!qdma->q_rx[i].ndesc) -- continue; -- -- netif_napi_del(&qdma->q_rx[i].napi); -- airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]); -- if (qdma->q_rx[i].page_pool) -- page_pool_destroy(qdma->q_rx[i].page_pool); -- } -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -- netif_napi_del(&qdma->q_tx_irq[i].napi); -- -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { -- if (!qdma->q_tx[i].ndesc) -- continue; -- -- airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]); -- } -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -+ airoha_qdma_cleanup(ð->qdma[i]); -+ airoha_ppe_deinit(eth); - } - - static void airoha_qdma_start_napi(struct airoha_qdma *qdma) -@@ -3033,7 +3049,7 @@ static int airoha_probe(struct platform_ - - err = airoha_hw_init(pdev, eth); - if (err) -- goto error_hw_cleanup; -+ goto error_netdev_free; - - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) - airoha_qdma_start_napi(ð->qdma[i]); -@@ -3061,10 +3077,6 @@ static int airoha_probe(struct platform_ - error_napi_stop: - for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) - airoha_qdma_stop_napi(ð->qdma[i]); -- airoha_ppe_deinit(eth); --error_hw_cleanup: -- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) -- airoha_hw_cleanup(ð->qdma[i]); - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -@@ -3076,6 +3088,8 @@ error_hw_cleanup: - unregister_netdev(port->dev); - airoha_metadata_dst_free(port); - } -+ airoha_hw_cleanup(eth); -+error_netdev_free: - free_netdev(eth->napi_dev); - platform_set_drvdata(pdev, NULL); - -@@ -3087,10 +3101,8 @@ static void airoha_remove(struct platfor - struct airoha_eth *eth = platform_get_drvdata(pdev); - int i; - -- for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) { -+ for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) - airoha_qdma_stop_napi(ð->qdma[i]); -- airoha_hw_cleanup(ð->qdma[i]); -- } - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -@@ -3101,9 +3113,9 @@ static void airoha_remove(struct platfor - unregister_netdev(port->dev); - airoha_metadata_dst_free(port); - } -- free_netdev(eth->napi_dev); -+ airoha_hw_cleanup(eth); - -- airoha_ppe_deinit(eth); -+ free_netdev(eth->napi_dev); - platform_set_drvdata(pdev, NULL); - } - diff --git a/target/linux/airoha/patches-6.12/134-v7.1-net-airoha-Delay-offloading-until-all-net_devices-ar.patch b/target/linux/airoha/patches-6.12/134-v7.1-net-airoha-Delay-offloading-until-all-net_devices-ar.patch deleted file mode 100644 index 14be9c1925b..00000000000 --- a/target/linux/airoha/patches-6.12/134-v7.1-net-airoha-Delay-offloading-until-all-net_devices-ar.patch +++ /dev/null @@ -1,63 +0,0 @@ -From cedc1bf327de62ec30af9743bd1f601c2de30553 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 29 Mar 2026 12:32:27 +0200 -Subject: [PATCH] net: airoha: Delay offloading until all net_devices are fully - registered - -Netfilter flowtable can theoretically try to offload flower rules as soon -as a net_device is registered while all the other ones are not -registered or initialized, triggering a possible NULL pointer dereferencing -of qdma pointer in airoha_ppe_set_cpu_port routine. Moreover, if -register_netdev() fails for a particular net_device, there is a small -race if Netfilter tries to offload flowtable rules before all the -net_devices are properly unregistered in airoha_probe() error patch, -triggering a NULL pointer dereferencing in airoha_ppe_set_cpu_port -routine. In order to avoid any possible race, delay offloading until -all net_devices are registered in the networking subsystem. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260329-airoha-regiser-race-fix-v2-1-f4ebb139277b@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 2 ++ - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - drivers/net/ethernet/airoha/airoha_ppe.c | 7 +++++++ - 3 files changed, 10 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2978,6 +2978,8 @@ static int airoha_register_gdm_devices(s - return err; - } - -+ set_bit(DEV_STATE_REGISTERED, ð->state); -+ - return 0; - } - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -88,6 +88,7 @@ enum { - - enum { - DEV_STATE_INITIALIZED, -+ DEV_STATE_REGISTERED, - }; - - enum { ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -1387,6 +1387,13 @@ int airoha_ppe_setup_tc_block_cb(struct - struct airoha_eth *eth = ppe->eth; - int err = 0; - -+ /* Netfilter flowtable can try to offload flower rules while not all -+ * the net_devices are registered or initialized. Delay offloading -+ * until all net_devices are registered in the system. -+ */ -+ if (!test_bit(DEV_STATE_REGISTERED, ð->state)) -+ return -EBUSY; -+ - mutex_lock(&flow_offload_mutex); - - if (!eth->npu) diff --git a/target/linux/airoha/patches-6.12/136-v7.1-net-airoha-Add-dma_rmb-and-READ_ONCE-in-airoha_qdma_.patch b/target/linux/airoha/patches-6.12/136-v7.1-net-airoha-Add-dma_rmb-and-READ_ONCE-in-airoha_qdma_.patch deleted file mode 100644 index 6cceacfbc65..00000000000 --- a/target/linux/airoha/patches-6.12/136-v7.1-net-airoha-Add-dma_rmb-and-READ_ONCE-in-airoha_qdma_.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 4ae0604a0673e11e2075b178387151fcad5111b5 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 7 Apr 2026 08:48:04 +0200 -Subject: [PATCH] net: airoha: Add dma_rmb() and READ_ONCE() in - airoha_qdma_rx_process() - -Add missing dma_rmb() in airoha_qdma_rx_process routine to make sure the -DMA read operations are completed when the NIC reports the processing on -the current descriptor is done. Moreover, add missing READ_ONCE() in -airoha_qdma_rx_process() for DMA descriptor control fields in order to -avoid any compiler reordering. - -Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260407-airoha_qdma_rx_process-fix-reordering-v3-1-91c36e9da31f@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++++------ - 1 file changed, 10 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -584,7 +584,7 @@ static int airoha_qdma_fill_rx_queue(str - static int airoha_qdma_get_gdm_port(struct airoha_eth *eth, - struct airoha_qdma_desc *desc) - { -- u32 port, sport, msg1 = le32_to_cpu(desc->msg1); -+ u32 port, sport, msg1 = le32_to_cpu(READ_ONCE(desc->msg1)); - - sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); - switch (sport) { -@@ -612,21 +612,24 @@ static int airoha_qdma_rx_process(struct - while (done < budget) { - struct airoha_queue_entry *e = &q->entry[q->tail]; - struct airoha_qdma_desc *desc = &q->desc[q->tail]; -- u32 hash, reason, msg1 = le32_to_cpu(desc->msg1); -- struct page *page = virt_to_head_page(e->buf); -- u32 desc_ctrl = le32_to_cpu(desc->ctrl); -+ u32 hash, reason, msg1, desc_ctrl; - struct airoha_gdm_port *port; - int data_len, len, p; -+ struct page *page; - -+ desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl)); - if (!(desc_ctrl & QDMA_DESC_DONE_MASK)) - break; - -+ dma_rmb(); -+ - q->tail = (q->tail + 1) % q->ndesc; - q->queued--; - - dma_sync_single_for_cpu(eth->dev, e->dma_addr, - SKB_WITH_OVERHEAD(q->buf_size), dir); - -+ page = virt_to_head_page(e->buf); - len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); - data_len = q->skb ? q->buf_size - : SKB_WITH_OVERHEAD(q->buf_size); -@@ -670,8 +673,8 @@ static int airoha_qdma_rx_process(struct - * DMA descriptor. Report DSA tag to the DSA stack - * via skb dst info. - */ -- u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG, -- le32_to_cpu(desc->msg0)); -+ u32 msg0 = le32_to_cpu(READ_ONCE(desc->msg0)); -+ u32 sptag = FIELD_GET(QDMA_ETH_RXMSG_SPTAG, msg0); - - if (sptag < ARRAY_SIZE(port->dsa_meta) && - port->dsa_meta[sptag]) -@@ -679,6 +682,7 @@ static int airoha_qdma_rx_process(struct - &port->dsa_meta[sptag]->dst); - } - -+ msg1 = le32_to_cpu(READ_ONCE(desc->msg1)); - hash = FIELD_GET(AIROHA_RXD4_FOE_ENTRY, msg1); - if (hash != AIROHA_RXD4_FOE_ENTRY) - skb_set_hash(q->skb, jhash_1word(hash, 0), diff --git a/target/linux/airoha/patches-6.12/137-v7.1-net-airoha-Add-missing-PPE-configurations-in-airoha_.patch b/target/linux/airoha/patches-6.12/137-v7.1-net-airoha-Add-missing-PPE-configurations-in-airoha_.patch deleted file mode 100644 index a6089f9a9ef..00000000000 --- a/target/linux/airoha/patches-6.12/137-v7.1-net-airoha-Add-missing-PPE-configurations-in-airoha_.patch +++ /dev/null @@ -1,62 +0,0 @@ -From b9d8b856689d2b968495d79fe653d87fcb8ad98c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Apr 2026 10:43:26 +0200 -Subject: [PATCH] net: airoha: Add missing PPE configurations in - airoha_ppe_hw_init() - -Add the following PPE configuration in airoha_ppe_hw_init routine: -- 6RD hw offloading is currently not supported by Netfilter flowtable. - Disable explicitly PPE 6RD offloading in order to prevent PPE to learn - 6RD flows and eventually interrupt the traffic. -- Add missing PPE bind rate configuration for L3 and L2 traffic. - PPE bind rate configuration specifies the pps threshold to move a PPE - entry state from UNBIND to BIND. Without this configuration this value - is random. -- Set ageing thresholds to the values used in the vendor SDK in order to - improve connection stability under load and avoid packet loss caused by - fast aging. - -Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20260412-airoha_ppe_hw_init-missing-bits-v1-1-06ac670819e3@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -125,13 +125,13 @@ static void airoha_ppe_hw_init(struct ai - airoha_fe_rmw(eth, REG_PPE_BND_AGE0(i), - PPE_BIND_AGE0_DELTA_NON_L4 | - PPE_BIND_AGE0_DELTA_UDP, -- FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 1) | -- FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 12)); -+ FIELD_PREP(PPE_BIND_AGE0_DELTA_NON_L4, 60) | -+ FIELD_PREP(PPE_BIND_AGE0_DELTA_UDP, 60)); - airoha_fe_rmw(eth, REG_PPE_BND_AGE1(i), - PPE_BIND_AGE1_DELTA_TCP_FIN | - PPE_BIND_AGE1_DELTA_TCP, - FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP_FIN, 1) | -- FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 7)); -+ FIELD_PREP(PPE_BIND_AGE1_DELTA_TCP, 60)); - - airoha_fe_rmw(eth, REG_PPE_TB_HASH_CFG(i), - PPE_SRAM_TABLE_EN_MASK | -@@ -159,7 +159,15 @@ static void airoha_ppe_hw_init(struct ai - FIELD_PREP(PPE_DRAM_TB_NUM_ENTRY_MASK, - dram_num_entries)); - -+ airoha_fe_rmw(eth, REG_PPE_BIND_RATE(i), -+ PPE_BIND_RATE_L2B_BIND_MASK | -+ PPE_BIND_RATE_BIND_MASK, -+ FIELD_PREP(PPE_BIND_RATE_L2B_BIND_MASK, 0x1e) | -+ FIELD_PREP(PPE_BIND_RATE_BIND_MASK, 0x1e)); -+ - airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); -+ airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i), -+ PPE_FLOW_CFG_IP6_6RD_MASK); - - for (p = 0; p < ARRAY_SIZE(eth->ports); p++) { - struct airoha_gdm_port *port = eth->ports[p]; diff --git a/target/linux/airoha/patches-6.12/139-v7.1-net-airoha-Fix-FE_PSE_BUF_SET-configuration-if-PPE2-.patch b/target/linux/airoha/patches-6.12/139-v7.1-net-airoha-Fix-FE_PSE_BUF_SET-configuration-if-PPE2-.patch deleted file mode 100644 index 2053e0eff99..00000000000 --- a/target/linux/airoha/patches-6.12/139-v7.1-net-airoha-Fix-FE_PSE_BUF_SET-configuration-if-PPE2-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 02f72964395911e7a09bb2ea2fe6f79eda4ea2c2 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 8 Apr 2026 12:20:09 +0200 -Subject: [PATCH] net: airoha: Fix FE_PSE_BUF_SET configuration if PPE2 is - available - -airoha_fe_set routine is used to set specified bits to 1 in the selected -register. In the FE_PSE_BUF_SET case this can due to a overestimation of -the required buffers for I/O queues since we can miss to set some bits -of PSE_ALLRSV_MASK subfield to 0. Fix the issue relying on airoha_fe_rmw -routine instead. - -Fixes: 8e38e08f2c560 ("net: airoha: fix PSE memory configuration in airoha_fe_pse_ports_init()") -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260408-airoha-reg_fe_pse_buf_set-v1-1-0c4fa8f4d1d9@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -293,16 +293,18 @@ static void airoha_fe_pse_ports_init(str - [FE_PSE_PORT_GDM4] = 2, - [FE_PSE_PORT_CDM5] = 2, - }; -- u32 all_rsv; - int q; - -- all_rsv = airoha_fe_get_pse_all_rsv(eth); - if (airoha_ppe_is_enabled(eth, 1)) { -+ u32 all_rsv; -+ - /* hw misses PPE2 oq rsv */ -+ all_rsv = airoha_fe_get_pse_all_rsv(eth); - all_rsv += PSE_RSV_PAGES * - pse_port_num_queues[FE_PSE_PORT_PPE2]; -+ airoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK, -+ FIELD_PREP(PSE_ALLRSV_MASK, all_rsv)); - } -- airoha_fe_set(eth, REG_FE_PSE_BUF_SET, all_rsv); - - /* CMD1 */ - for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_CDM1]; q++) diff --git a/target/linux/airoha/patches-6.12/140-v7.1-net-airoha-Fix-memory-leak-in-airoha_qdma_rx_process.patch b/target/linux/airoha/patches-6.12/140-v7.1-net-airoha-Fix-memory-leak-in-airoha_qdma_rx_process.patch deleted file mode 100644 index 9d331d8d811..00000000000 --- a/target/linux/airoha/patches-6.12/140-v7.1-net-airoha-Fix-memory-leak-in-airoha_qdma_rx_process.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 285fa6b1e03cff78ead0383e1b259c44b95faf90 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 2 Apr 2026 14:57:10 +0200 -Subject: [PATCH] net: airoha: Fix memory leak in airoha_qdma_rx_process() - -If an error occurs on the subsequents buffers belonging to the -non-linear part of the skb (e.g. due to an error in the payload length -reported by the NIC or if we consumed all the available fragments for -the skb), the page_pool fragment will not be linked to the skb so it will -not return to the pool in the airoha_qdma_rx_process() error path. Fix the -memory leak partially reverting commit 'd6d2b0e1538d ("net: airoha: Fix -page recycling in airoha_qdma_rx_process()")' and always running -page_pool_put_full_page routine in the airoha_qdma_rx_process() error -path. - -Fixes: d6d2b0e1538d ("net: airoha: Fix page recycling in airoha_qdma_rx_process()") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20260402-airoha_qdma_rx_process-mem-leak-fix-v1-1-b5706f402d3c@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -703,9 +703,8 @@ free_frag: - if (q->skb) { - dev_kfree_skb(q->skb); - q->skb = NULL; -- } else { -- page_pool_put_full_page(q->page_pool, page, true); - } -+ page_pool_put_full_page(q->page_pool, page, true); - } - airoha_qdma_fill_rx_queue(q); - diff --git a/target/linux/airoha/patches-6.12/141-v7.1-net-airoha-Fix-VIP-configuration-for-AN7583-SoC.patch b/target/linux/airoha/patches-6.12/141-v7.1-net-airoha-Fix-VIP-configuration-for-AN7583-SoC.patch deleted file mode 100644 index 6b659879b50..00000000000 --- a/target/linux/airoha/patches-6.12/141-v7.1-net-airoha-Fix-VIP-configuration-for-AN7583-SoC.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 1acdfbdb516b32165a8ecd1d5f8c68e4eac64637 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Apr 2026 09:57:29 +0200 -Subject: [PATCH] net: airoha: Fix VIP configuration for AN7583 SoC - -EN7581 and AN7583 SoCs have different VIP definitions. Introduce -get_vip_port callback in airoha_eth_soc_data struct in order to take -into account EN7581 and AN7583 VIP register layout and definition -differences. -Introduce nbq parameter in airoha_gdm_port struct. At the moment nbq -is set statically to value previously used in airhoha_set_gdm2_loopback -routine and it will be read from device tree in subsequent patches. - -Fixes: e4e5ce823bdd ("net: airoha: Add AN7583 SoC support") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260412-airoha-7583-vip-fix-v1-1-c35e02b054bb@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 66 ++++++++++++++++++------ - drivers/net/ethernet/airoha/airoha_eth.h | 2 + - 2 files changed, 51 insertions(+), 17 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -107,19 +107,7 @@ static int airoha_set_vip_for_gdm_port(s - struct airoha_eth *eth = port->qdma->eth; - u32 vip_port; - -- switch (port->id) { -- case AIROHA_GDM3_IDX: -- /* FIXME: handle XSI_PCIE1_PORT */ -- vip_port = XSI_PCIE0_VIP_PORT_MASK; -- break; -- case AIROHA_GDM4_IDX: -- /* FIXME: handle XSI_USB_PORT */ -- vip_port = XSI_ETH_VIP_PORT_MASK; -- break; -- default: -- return 0; -- } -- -+ vip_port = eth->soc->ops.get_vip_port(port, port->nbq); - if (enable) { - airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); - airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); -@@ -1738,7 +1726,7 @@ static int airoha_dev_set_macaddr(struct - static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) - { - struct airoha_eth *eth = port->qdma->eth; -- u32 val, pse_port, chan, nbq; -+ u32 val, pse_port, chan; - int src_port; - - /* Forward the traffic to the proper GDM port */ -@@ -1768,9 +1756,7 @@ static int airhoha_set_gdm2_loopback(str - airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); - airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX)); - -- /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ -- nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; -- src_port = eth->soc->ops.get_src_port_id(port, nbq); -+ src_port = eth->soc->ops.get_src_port_id(port, port->nbq); - if (src_port < 0) - return src_port; - -@@ -1784,7 +1770,7 @@ static int airhoha_set_gdm2_loopback(str - __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2)); - - if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) { -- u32 mask = FC_ID_OF_SRC_PORT_MASK(nbq); -+ u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq); - - airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask, - __field_prep(mask, AIROHA_GDM2_IDX)); -@@ -2962,6 +2948,8 @@ static int airoha_alloc_gdm_port(struct - port->eth = eth; - port->dev = dev; - port->id = id; -+ /* XXX: Read nbq from DTS */ -+ port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; - eth->ports[p] = port; - - return airoha_metadata_dst_alloc(port); -@@ -3158,6 +3146,28 @@ static int airoha_en7581_get_src_port_id - return -EINVAL; - } - -+static u32 airoha_en7581_get_vip_port(struct airoha_gdm_port *port, int nbq) -+{ -+ switch (port->id) { -+ case AIROHA_GDM3_IDX: -+ if (nbq == 4) -+ return XSI_PCIE0_VIP_PORT_MASK; -+ if (nbq == 5) -+ return XSI_PCIE1_VIP_PORT_MASK; -+ break; -+ case AIROHA_GDM4_IDX: -+ if (!nbq) -+ return XSI_ETH_VIP_PORT_MASK; -+ if (nbq == 1) -+ return XSI_USB_VIP_PORT_MASK; -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ - static const char * const an7583_xsi_rsts_names[] = { - "xsi-mac", - "hsi0-mac", -@@ -3187,6 +3197,26 @@ static int airoha_an7583_get_src_port_id - return -EINVAL; - } - -+static u32 airoha_an7583_get_vip_port(struct airoha_gdm_port *port, int nbq) -+{ -+ switch (port->id) { -+ case AIROHA_GDM3_IDX: -+ if (!nbq) -+ return XSI_ETH_VIP_PORT_MASK; -+ break; -+ case AIROHA_GDM4_IDX: -+ if (!nbq) -+ return XSI_PCIE0_VIP_PORT_MASK; -+ if (nbq == 1) -+ return XSI_USB_VIP_PORT_MASK; -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ - static const struct airoha_eth_soc_data en7581_soc_data = { - .version = 0x7581, - .xsi_rsts_names = en7581_xsi_rsts_names, -@@ -3194,6 +3224,7 @@ static const struct airoha_eth_soc_data - .num_ppe = 2, - .ops = { - .get_src_port_id = airoha_en7581_get_src_port_id, -+ .get_vip_port = airoha_en7581_get_vip_port, - }, - }; - -@@ -3204,6 +3235,7 @@ static const struct airoha_eth_soc_data - .num_ppe = 1, - .ops = { - .get_src_port_id = airoha_an7583_get_src_port_id, -+ .get_vip_port = airoha_an7583_get_vip_port, - }, - }; - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -537,6 +537,7 @@ struct airoha_gdm_port { - struct airoha_eth *eth; - struct net_device *dev; - int id; -+ int nbq; - - struct airoha_hw_stats stats; - -@@ -577,6 +578,7 @@ struct airoha_eth_soc_data { - int num_ppe; - struct { - int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq); -+ u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq); - } ops; - }; - diff --git a/target/linux/airoha/patches-6.12/142-01-v7.1-net-airoha-Rely-on-net_device-pointer-in-airoha_dev_.patch b/target/linux/airoha/patches-6.12/142-01-v7.1-net-airoha-Rely-on-net_device-pointer-in-airoha_dev_.patch deleted file mode 100644 index d09272a8af6..00000000000 --- a/target/linux/airoha/patches-6.12/142-01-v7.1-net-airoha-Rely-on-net_device-pointer-in-airoha_dev_.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 360d745a5319f09849a94dee0974c8ead721e392 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Apr 2026 19:13:12 +0200 -Subject: [PATCH 1/4] net: airoha: Rely on net_device pointer in - airoha_dev_setup_tc_block signature - -Remove airoha_gdm_port dependency in airoha_dev_setup_tc_block routine -signature and rely on net_device pointer instead. Please note this patch -does not introduce any logical change and it is a preliminary patch to -support multiple net_devices connected to the GDM3 or GDM4 ports via an -external hw arbiter. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260412-airoha-multi-serdes-preliminary-patch-v1-1-08d5b670ca8f@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2683,7 +2683,7 @@ static int airoha_dev_setup_tc_block_cb( - } - } - --static int airoha_dev_setup_tc_block(struct airoha_gdm_port *port, -+static int airoha_dev_setup_tc_block(struct net_device *dev, - struct flow_block_offload *f) - { - flow_setup_cb_t *cb = airoha_dev_setup_tc_block_cb; -@@ -2696,12 +2696,12 @@ static int airoha_dev_setup_tc_block(str - f->driver_block_list = &block_cb_list; - switch (f->command) { - case FLOW_BLOCK_BIND: -- block_cb = flow_block_cb_lookup(f->block, cb, port->dev); -+ block_cb = flow_block_cb_lookup(f->block, cb, dev); - if (block_cb) { - flow_block_cb_incref(block_cb); - return 0; - } -- block_cb = flow_block_cb_alloc(cb, port->dev, port->dev, NULL); -+ block_cb = flow_block_cb_alloc(cb, dev, dev, NULL); - if (IS_ERR(block_cb)) - return PTR_ERR(block_cb); - -@@ -2710,7 +2710,7 @@ static int airoha_dev_setup_tc_block(str - list_add_tail(&block_cb->driver_list, &block_cb_list); - return 0; - case FLOW_BLOCK_UNBIND: -- block_cb = flow_block_cb_lookup(f->block, cb, port->dev); -+ block_cb = flow_block_cb_lookup(f->block, cb, dev); - if (!block_cb) - return -ENOENT; - -@@ -2809,7 +2809,7 @@ static int airoha_dev_tc_setup(struct ne - return airoha_tc_setup_qdisc_htb(port, type_data); - case TC_SETUP_BLOCK: - case TC_SETUP_FT: -- return airoha_dev_setup_tc_block(port, type_data); -+ return airoha_dev_setup_tc_block(dev, type_data); - default: - return -EOPNOTSUPP; - } diff --git a/target/linux/airoha/patches-6.12/142-02-v7.1-net-airoha-Rely-on-net_device-pointer-in-HTB-callbac.patch b/target/linux/airoha/patches-6.12/142-02-v7.1-net-airoha-Rely-on-net_device-pointer-in-HTB-callbac.patch deleted file mode 100644 index 76651dbe601..00000000000 --- a/target/linux/airoha/patches-6.12/142-02-v7.1-net-airoha-Rely-on-net_device-pointer-in-HTB-callbac.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 8baf4bf72ef94c955ef89d4644f1986603ee8320 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Apr 2026 19:13:13 +0200 -Subject: [PATCH 2/4] net: airoha: Rely on net_device pointer in HTB callbacks - -Remove airoha_gdm_port dependency in HTB tc callback signatures and rely -on net_device pointer instead. Please note this patch does not introduce -any logical change and it is a preliminary patch in order to support -multiple net_devices connected to the same GDM3 or GDM4 port via an -external hw arbiter. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260412-airoha-multi-serdes-preliminary-patch-v1-2-08d5b670ca8f@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 45 +++++++++++++----------- - 1 file changed, 24 insertions(+), 21 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2488,10 +2488,11 @@ static int airoha_qdma_set_trtcm_token_b - mode, val); - } - --static int airoha_qdma_set_tx_rate_limit(struct airoha_gdm_port *port, -+static int airoha_qdma_set_tx_rate_limit(struct net_device *dev, - int channel, u32 rate, - u32 bucket_size) - { -+ struct airoha_gdm_port *port = netdev_priv(dev); - int i, err; - - for (i = 0; i <= TRTCM_PEAK_MODE; i++) { -@@ -2511,21 +2512,20 @@ static int airoha_qdma_set_tx_rate_limit - return 0; - } - --static int airoha_tc_htb_alloc_leaf_queue(struct airoha_gdm_port *port, -+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev, - struct tc_htb_qopt_offload *opt) - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; - u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ -- struct net_device *dev = port->dev; -- int num_tx_queues = dev->real_num_tx_queues; -- int err; -+ int err, num_tx_queues = dev->real_num_tx_queues; -+ struct airoha_gdm_port *port = netdev_priv(dev); - - if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); - return -EINVAL; - } - -- err = airoha_qdma_set_tx_rate_limit(port, channel, rate, opt->quantum); -+ err = airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum); - if (err) { - NL_SET_ERR_MSG_MOD(opt->extack, - "failed configuring htb offload"); -@@ -2537,7 +2537,7 @@ static int airoha_tc_htb_alloc_leaf_queu - - err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); - if (err) { -- airoha_qdma_set_tx_rate_limit(port, channel, 0, opt->quantum); -+ airoha_qdma_set_tx_rate_limit(dev, channel, 0, opt->quantum); - NL_SET_ERR_MSG_MOD(opt->extack, - "failed setting real_num_tx_queues"); - return err; -@@ -2724,44 +2724,47 @@ static int airoha_dev_setup_tc_block(str - } - } - --static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue) -+static void airoha_tc_remove_htb_queue(struct net_device *dev, int queue) - { -- struct net_device *dev = port->dev; -+ struct airoha_gdm_port *port = netdev_priv(dev); - - netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); -- airoha_qdma_set_tx_rate_limit(port, queue + 1, 0, 0); -+ airoha_qdma_set_tx_rate_limit(dev, queue + 1, 0, 0); - clear_bit(queue, port->qos_sq_bmap); - } - --static int airoha_tc_htb_delete_leaf_queue(struct airoha_gdm_port *port, -+static int airoha_tc_htb_delete_leaf_queue(struct net_device *dev, - struct tc_htb_qopt_offload *opt) - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ struct airoha_gdm_port *port = netdev_priv(dev); - - if (!test_bit(channel, port->qos_sq_bmap)) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); - return -EINVAL; - } - -- airoha_tc_remove_htb_queue(port, channel); -+ airoha_tc_remove_htb_queue(dev, channel); - - return 0; - } - --static int airoha_tc_htb_destroy(struct airoha_gdm_port *port) -+static int airoha_tc_htb_destroy(struct net_device *dev) - { -+ struct airoha_gdm_port *port = netdev_priv(dev); - int q; - - for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) -- airoha_tc_remove_htb_queue(port, q); -+ airoha_tc_remove_htb_queue(dev, q); - - return 0; - } - --static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port, -+static int airoha_tc_get_htb_get_leaf_queue(struct net_device *dev, - struct tc_htb_qopt_offload *opt) - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ struct airoha_gdm_port *port = netdev_priv(dev); - - if (!test_bit(channel, port->qos_sq_bmap)) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -@@ -2773,23 +2776,23 @@ static int airoha_tc_get_htb_get_leaf_qu - return 0; - } - --static int airoha_tc_setup_qdisc_htb(struct airoha_gdm_port *port, -+static int airoha_tc_setup_qdisc_htb(struct net_device *dev, - struct tc_htb_qopt_offload *opt) - { - switch (opt->command) { - case TC_HTB_CREATE: - break; - case TC_HTB_DESTROY: -- return airoha_tc_htb_destroy(port); -+ return airoha_tc_htb_destroy(dev); - case TC_HTB_NODE_MODIFY: - case TC_HTB_LEAF_ALLOC_QUEUE: -- return airoha_tc_htb_alloc_leaf_queue(port, opt); -+ return airoha_tc_htb_alloc_leaf_queue(dev, opt); - case TC_HTB_LEAF_DEL: - case TC_HTB_LEAF_DEL_LAST: - case TC_HTB_LEAF_DEL_LAST_FORCE: -- return airoha_tc_htb_delete_leaf_queue(port, opt); -+ return airoha_tc_htb_delete_leaf_queue(dev, opt); - case TC_HTB_LEAF_QUERY_QUEUE: -- return airoha_tc_get_htb_get_leaf_queue(port, opt); -+ return airoha_tc_get_htb_get_leaf_queue(dev, opt); - default: - return -EOPNOTSUPP; - } -@@ -2806,7 +2809,7 @@ static int airoha_dev_tc_setup(struct ne - case TC_SETUP_QDISC_ETS: - return airoha_tc_setup_qdisc_ets(port, type_data); - case TC_SETUP_QDISC_HTB: -- return airoha_tc_setup_qdisc_htb(port, type_data); -+ return airoha_tc_setup_qdisc_htb(dev, type_data); - case TC_SETUP_BLOCK: - case TC_SETUP_FT: - return airoha_dev_setup_tc_block(dev, type_data); diff --git a/target/linux/airoha/patches-6.12/142-03-v7.1-net-airoha-Rely-on-net_device-pointer-in-ETS-callbac.patch b/target/linux/airoha/patches-6.12/142-03-v7.1-net-airoha-Rely-on-net_device-pointer-in-ETS-callbac.patch deleted file mode 100644 index a8b15717c0b..00000000000 --- a/target/linux/airoha/patches-6.12/142-03-v7.1-net-airoha-Rely-on-net_device-pointer-in-ETS-callbac.patch +++ /dev/null @@ -1,118 +0,0 @@ -From ae32f80018f0f0f4ebc7a0a70d4092d08a1545e8 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Apr 2026 19:13:14 +0200 -Subject: [PATCH 3/4] net: airoha: Rely on net_device pointer in ETS callbacks - -Remove airoha_gdm_port dependency in ETS tc callback signatures and rely -on net_device pointer instead. Please note this patch does not introduce -any logical change and it is a preliminary patch in order to support -multiple net_devices connected to the same GDM3 or GDM4 port via an -external hw arbiter. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260412-airoha-multi-serdes-preliminary-patch-v1-3-08d5b670ca8f@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 30 +++++++++++------------- - 1 file changed, 14 insertions(+), 16 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2134,10 +2134,11 @@ airoha_ethtool_get_rmon_stats(struct net - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } - --static int airoha_qdma_set_chan_tx_sched(struct airoha_gdm_port *port, -+static int airoha_qdma_set_chan_tx_sched(struct net_device *dev, - int channel, enum tx_sched_mode mode, - const u16 *weights, u8 n_weights) - { -+ struct airoha_gdm_port *port = netdev_priv(dev); - int i; - - for (i = 0; i < AIROHA_NUM_TX_RING; i++) -@@ -2169,17 +2170,15 @@ static int airoha_qdma_set_chan_tx_sched - return 0; - } - --static int airoha_qdma_set_tx_prio_sched(struct airoha_gdm_port *port, -- int channel) -+static int airoha_qdma_set_tx_prio_sched(struct net_device *dev, int channel) - { - static const u16 w[AIROHA_NUM_QOS_QUEUES] = {}; - -- return airoha_qdma_set_chan_tx_sched(port, channel, TC_SCH_SP, w, -+ return airoha_qdma_set_chan_tx_sched(dev, channel, TC_SCH_SP, w, - ARRAY_SIZE(w)); - } - --static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port, -- int channel, -+static int airoha_qdma_set_tx_ets_sched(struct net_device *dev, int channel, - struct tc_ets_qopt_offload *opt) - { - struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params; -@@ -2220,20 +2219,21 @@ static int airoha_qdma_set_tx_ets_sched( - else if (nstrict < AIROHA_NUM_QOS_QUEUES - 1) - mode = nstrict + 1; - -- return airoha_qdma_set_chan_tx_sched(port, channel, mode, w, -+ return airoha_qdma_set_chan_tx_sched(dev, channel, mode, w, - ARRAY_SIZE(w)); - } - --static int airoha_qdma_get_tx_ets_stats(struct airoha_gdm_port *port, -- int channel, -+static int airoha_qdma_get_tx_ets_stats(struct net_device *dev, int channel, - struct tc_ets_qopt_offload *opt) - { -+ struct airoha_gdm_port *port = netdev_priv(dev); - u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, - REG_CNTR_VAL(channel << 1)); - u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, - REG_CNTR_VAL((channel << 1) + 1)); - u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + - (fwd_tx_packets - port->fwd_tx_packets); -+ - _bstats_update(opt->stats.bstats, 0, tx_packets); - - port->cpu_tx_packets = cpu_tx_packets; -@@ -2242,7 +2242,7 @@ static int airoha_qdma_get_tx_ets_stats( - return 0; - } - --static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port, -+static int airoha_tc_setup_qdisc_ets(struct net_device *dev, - struct tc_ets_qopt_offload *opt) - { - int channel; -@@ -2255,12 +2255,12 @@ static int airoha_tc_setup_qdisc_ets(str - - switch (opt->command) { - case TC_ETS_REPLACE: -- return airoha_qdma_set_tx_ets_sched(port, channel, opt); -+ return airoha_qdma_set_tx_ets_sched(dev, channel, opt); - case TC_ETS_DESTROY: - /* PRIO is default qdisc scheduler */ -- return airoha_qdma_set_tx_prio_sched(port, channel); -+ return airoha_qdma_set_tx_prio_sched(dev, channel); - case TC_ETS_STATS: -- return airoha_qdma_get_tx_ets_stats(port, channel, opt); -+ return airoha_qdma_get_tx_ets_stats(dev, channel, opt); - default: - return -EOPNOTSUPP; - } -@@ -2803,11 +2803,9 @@ static int airoha_tc_setup_qdisc_htb(str - static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, - void *type_data) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -- - switch (type) { - case TC_SETUP_QDISC_ETS: -- return airoha_tc_setup_qdisc_ets(port, type_data); -+ return airoha_tc_setup_qdisc_ets(dev, type_data); - case TC_SETUP_QDISC_HTB: - return airoha_tc_setup_qdisc_htb(dev, type_data); - case TC_SETUP_BLOCK: diff --git a/target/linux/airoha/patches-6.12/142-04-v7.1-net-airoha-Remove-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch b/target/linux/airoha/patches-6.12/142-04-v7.1-net-airoha-Remove-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch deleted file mode 100644 index 3067915a3cf..00000000000 --- a/target/linux/airoha/patches-6.12/142-04-v7.1-net-airoha-Remove-PCE_MC_EN_MASK-bit-in-REG_FE_PCE_C.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 34e1a98ff2a87cf4b8de3ccebe9d45273f014aeb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sun, 12 Apr 2026 11:56:25 +0200 -Subject: [PATCH 4/4] net: airoha: Remove PCE_MC_EN_MASK bit in REG_FE_PCE_CFG - configuration - -PCE_MC_EN_MASK bit in REG_FE_PCE_CFG configuration performed in -airoha_fe_init() is used to duplicate multicast packets and send a copy -to the CPU when the traffic is offloaded. This is necessary just if -it is requested by the user. Disable multicast packets duplication by -default. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260412-airoha_fe_init_remove_mc_en_bit-v1-1-7b6a5a25a74d@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -448,9 +448,8 @@ static int airoha_fe_init(struct airoha_ - FIELD_PREP(PSE_IQ_RES2_P5_MASK, 0x40) | - FIELD_PREP(PSE_IQ_RES2_P4_MASK, 0x34)); - -- /* enable FE copy engine for MC/KA/DPI */ -- airoha_fe_wr(eth, REG_FE_PCE_CFG, -- PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); -+ /* enable FE copy engine for KA/DPI */ -+ airoha_fe_wr(eth, REG_FE_PCE_CFG, PCE_DPI_EN_MASK | PCE_KA_EN_MASK); - /* set vip queue selection to ring 1 */ - airoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK, - FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4)); diff --git a/target/linux/airoha/patches-6.12/143-v7.1-net-airoha-Fix-typo-in-airoha_set_gdm2_loopback-rout.patch b/target/linux/airoha/patches-6.12/143-v7.1-net-airoha-Fix-typo-in-airoha_set_gdm2_loopback-rout.patch deleted file mode 100644 index dcbc223ca1b..00000000000 --- a/target/linux/airoha/patches-6.12/143-v7.1-net-airoha-Fix-typo-in-airoha_set_gdm2_loopback-rout.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a94ddc191f19579a7e0a5da2c012f1048ce10262 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 30 Mar 2026 00:03:49 +0200 -Subject: [PATCH] net: airoha: Fix typo in airoha_set_gdm2_loopback routine - name - -Rename airhoha_set_gdm2_loopback() in airoha_set_gdm2_loopback() - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260330-airoha_set_gdm2_loopback-fix-typo-v1-1-a1320ff6b6cc@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1722,7 +1722,7 @@ static int airoha_dev_set_macaddr(struct - return 0; - } - --static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) -+static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port) - { - struct airoha_eth *eth = port->qdma->eth; - u32 val, pse_port, chan; -@@ -1796,7 +1796,7 @@ static int airoha_dev_init(struct net_de - if (!eth->ports[1]) { - int err; - -- err = airhoha_set_gdm2_loopback(port); -+ err = airoha_set_gdm2_loopback(port); - if (err) - return err; - } diff --git a/target/linux/airoha/patches-6.12/144-v7.1-net-airoha-Set-REG_RX_CPU_IDX-once-in-airoha_qdma_fi.patch b/target/linux/airoha/patches-6.12/144-v7.1-net-airoha-Set-REG_RX_CPU_IDX-once-in-airoha_qdma_fi.patch deleted file mode 100644 index 8a982330b26..00000000000 --- a/target/linux/airoha/patches-6.12/144-v7.1-net-airoha-Set-REG_RX_CPU_IDX-once-in-airoha_qdma_fi.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 269389ba539834ec80e4d55583fca2cd70e4dc9c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 31 Mar 2026 12:33:24 +0200 -Subject: [PATCH] net: airoha: Set REG_RX_CPU_IDX() once in - airoha_qdma_fill_rx_queue() - -It is not necessary to update REG_RX_CPU_IDX register for each iteration -of the descriptor loop in airoha_qdma_fill_rx_queue routine. -Move REG_RX_CPU_IDX configuration out of the descriptor loop and rely on -the last queue head value updated in the descriptor loop. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260331-airoha-cpu-idx-out-off-loop-v1-1-75c66b428f50@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -561,11 +561,12 @@ static int airoha_qdma_fill_rx_queue(str - WRITE_ONCE(desc->msg1, 0); - WRITE_ONCE(desc->msg2, 0); - WRITE_ONCE(desc->msg3, 0); -+ } - -+ if (nframes) - airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), - RX_RING_CPU_IDX_MASK, - FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head)); -- } - - return nframes; - } diff --git a/target/linux/airoha/patches-6.12/145-01-v7.1-net-airoha-Move-ndesc-initialization-at-end-of-airoh.patch b/target/linux/airoha/patches-6.12/145-01-v7.1-net-airoha-Move-ndesc-initialization-at-end-of-airoh.patch deleted file mode 100644 index c4045cc8af4..00000000000 --- a/target/linux/airoha/patches-6.12/145-01-v7.1-net-airoha-Move-ndesc-initialization-at-end-of-airoh.patch +++ /dev/null @@ -1,55 +0,0 @@ -From f329924bb49458c65297f1361f545816a5b90998 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Apr 2026 08:36:31 +0200 -Subject: [PATCH 1/2] net: airoha: Move ndesc initialization at end of - airoha_qdma_init_tx() - -If queue entry list allocation fails in airoha_qdma_init_tx_queue routine, -airoha_qdma_cleanup_tx_queue() will trigger a NULL pointer dereference -accessing the queue entry array. The issue is due to the early ndesc -initialization in airoha_qdma_init_tx_queue(). Fix the issue moving ndesc -initialization at end of airoha_qdma_init_tx routine. - -Fixes: 3f47e67dff1f7 ("net: airoha: Add the capability to consume out-of-order DMA tx descriptors") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260417-airoha_qdma_cleanup_tx_queue-fix-net-v4-1-e04bcc2c9642@kernel.org -Reviewed-by: Simon Horman -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -954,27 +954,27 @@ static int airoha_qdma_init_tx_queue(str - dma_addr_t dma_addr; - - spin_lock_init(&q->lock); -- q->ndesc = size; - q->qdma = qdma; - q->free_thr = 1 + MAX_SKB_FRAGS; - INIT_LIST_HEAD(&q->tx_list); - -- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), -+ q->entry = devm_kzalloc(eth->dev, size * sizeof(*q->entry), - GFP_KERNEL); - if (!q->entry) - return -ENOMEM; - -- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), -+ q->desc = dmam_alloc_coherent(eth->dev, size * sizeof(*q->desc), - &dma_addr, GFP_KERNEL); - if (!q->desc) - return -ENOMEM; - -- for (i = 0; i < q->ndesc; i++) { -+ for (i = 0; i < size; i++) { - u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); - - list_add_tail(&q->entry[i].list, &q->tx_list); - WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); - } -+ q->ndesc = size; - - /* xmit ring drop default setting */ - airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), diff --git a/target/linux/airoha/patches-6.12/145-02-v7.1-net-airoha-Add-missing-bits-in-airoha_qdma_cleanup_t.patch b/target/linux/airoha/patches-6.12/145-02-v7.1-net-airoha-Add-missing-bits-in-airoha_qdma_cleanup_t.patch deleted file mode 100644 index 424a45c50b3..00000000000 --- a/target/linux/airoha/patches-6.12/145-02-v7.1-net-airoha-Add-missing-bits-in-airoha_qdma_cleanup_t.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 3309965fe44c00fd65af7cef5016e9e782c021a7 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Apr 2026 08:36:32 +0200 -Subject: [PATCH 2/2] net: airoha: Add missing bits in - airoha_qdma_cleanup_tx_queue() - -Similar to airoha_qdma_cleanup_rx_queue(), reset DMA TX descriptors in -airoha_qdma_cleanup_tx_queue routine. Moreover, reset TX_DMA_IDX to -TX_CPU_IDX to notify the NIC the QDMA TX ring is empty. - -Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260417-airoha_qdma_cleanup_tx_queue-fix-net-v4-2-e04bcc2c9642@kernel.org -Reviewed-by: Simon Horman -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 32 ++++++++++++++++++++++-- - 1 file changed, 30 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1039,12 +1039,15 @@ static int airoha_qdma_init_tx(struct ai - - static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q) - { -- struct airoha_eth *eth = q->qdma->eth; -- int i; -+ struct airoha_qdma *qdma = q->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ int i, qid = q - &qdma->q_tx[0]; -+ u16 index = 0; - - spin_lock_bh(&q->lock); - for (i = 0; i < q->ndesc; i++) { - struct airoha_queue_entry *e = &q->entry[i]; -+ struct airoha_qdma_desc *desc = &q->desc[i]; - - if (!e->dma_addr) - continue; -@@ -1055,8 +1058,33 @@ static void airoha_qdma_cleanup_tx_queue - e->dma_addr = 0; - e->skb = NULL; - list_add_tail(&e->list, &q->tx_list); -+ -+ /* Reset DMA descriptor */ -+ WRITE_ONCE(desc->ctrl, 0); -+ WRITE_ONCE(desc->addr, 0); -+ WRITE_ONCE(desc->data, 0); -+ WRITE_ONCE(desc->msg0, 0); -+ WRITE_ONCE(desc->msg1, 0); -+ WRITE_ONCE(desc->msg2, 0); -+ - q->queued--; - } -+ -+ if (!list_empty(&q->tx_list)) { -+ struct airoha_queue_entry *e; -+ -+ e = list_first_entry(&q->tx_list, struct airoha_queue_entry, -+ list); -+ index = e - q->entry; -+ } -+ /* Set TX_DMA_IDX to TX_CPU_IDX to notify the hw the QDMA TX ring is -+ * empty. -+ */ -+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK, -+ FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); -+ airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK, -+ FIELD_PREP(TX_RING_DMA_IDX_MASK, index)); -+ - spin_unlock_bh(&q->lock); - } - diff --git a/target/linux/airoha/patches-6.12/146-v7.1-net-airoha-Wait-for-NPU-PPE-configuration-to-complet.patch b/target/linux/airoha/patches-6.12/146-v7.1-net-airoha-Wait-for-NPU-PPE-configuration-to-complet.patch deleted file mode 100644 index d7b4680b52a..00000000000 --- a/target/linux/airoha/patches-6.12/146-v7.1-net-airoha-Wait-for-NPU-PPE-configuration-to-complet.patch +++ /dev/null @@ -1,63 +0,0 @@ -From f3206328bb52c2787197d80d7cbd687946047d5f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 14 Apr 2026 16:08:52 +0200 -Subject: [PATCH] net: airoha: Wait for NPU PPE configuration to complete in - airoha_ppe_offload_setup() - -In order to properly enable flowtable hw offloading, poll -REG_PPE_FLOW_CFG register in airoha_ppe_offload_setup routine and -wait for NPU PPE configuration triggered by ppe_init callback to complete -before running airoha_ppe_hw_init(). - -Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260414-airoha-wait-for-npu-config-offload-setup-v2-1-5a9bf6d43aee@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 28 ++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -1354,6 +1354,29 @@ static struct airoha_npu *airoha_ppe_npu - return npu; - } - -+static int airoha_ppe_wait_for_npu_init(struct airoha_eth *eth) -+{ -+ int err; -+ u32 val; -+ -+ /* PPE_FLOW_CFG default register value is 0. Since we reset FE -+ * during the device probe we can just check the configured value -+ * is not 0 here. -+ */ -+ err = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC, -+ 100 * USEC_PER_MSEC, false, eth, -+ REG_PPE_PPE_FLOW_CFG(0)); -+ if (err) -+ return err; -+ -+ if (airoha_ppe_is_enabled(eth, 1)) -+ err = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC, -+ 100 * USEC_PER_MSEC, false, eth, -+ REG_PPE_PPE_FLOW_CFG(1)); -+ -+ return err; -+} -+ - static int airoha_ppe_offload_setup(struct airoha_eth *eth) - { - struct airoha_npu *npu = airoha_ppe_npu_get(eth); -@@ -1367,6 +1390,11 @@ static int airoha_ppe_offload_setup(stru - if (err) - goto error_npu_put; - -+ /* Wait for NPU PPE configuration to complete */ -+ err = airoha_ppe_wait_for_npu_init(eth); -+ if (err) -+ goto error_npu_put; -+ - ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe); - if (ppe_num_stats_entries > 0) { - err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma, diff --git a/target/linux/airoha/patches-6.12/147-v7.1-net-airoha-Fix-PPE-cpu-port-configuration-for-GDM2-l.patch b/target/linux/airoha/patches-6.12/147-v7.1-net-airoha-Fix-PPE-cpu-port-configuration-for-GDM2-l.patch deleted file mode 100644 index 39b0fdfd909..00000000000 --- a/target/linux/airoha/patches-6.12/147-v7.1-net-airoha-Fix-PPE-cpu-port-configuration-for-GDM2-l.patch +++ /dev/null @@ -1,91 +0,0 @@ -From d647f2545219754603b2064de948425cdfd93fba Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 17 Apr 2026 17:24:41 +0200 -Subject: [PATCH] net: airoha: Fix PPE cpu port configuration for GDM2 loopback - path - -When QoS loopback is enabled for GDM3 or GDM4, incoming packets are -forwarded to GDM2. However, the PPE cpu port for GDM2 is not configured -in this path, causing traffic originating from GDM3/GDM4, which may -be set up as WAN ports backed by QDMA1, to be incorrectly directed -to QDMA0 instead. -Configure the PPE cpu port for GDM2 when QoS loopback is active on -GDM3 or GDM4 to ensure traffic is routed to the correct QDMA instance. - -Fixes: 9cd451d414f6 ("net: airoha: Add loopback support for GDM2") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260417-airoha-ppe-cpu-port-for-gdm2-loopback-v1-1-c7a9de0f6f57@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++++-- - drivers/net/ethernet/airoha/airoha_eth.h | 3 ++- - drivers/net/ethernet/airoha/airoha_ppe.c | 6 +++--- - 3 files changed, 11 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1755,7 +1755,7 @@ static int airoha_set_gdm2_loopback(stru - { - struct airoha_eth *eth = port->qdma->eth; - u32 val, pse_port, chan; -- int src_port; -+ int i, src_port; - - /* Forward the traffic to the proper GDM port */ - pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 -@@ -1797,6 +1797,9 @@ static int airoha_set_gdm2_loopback(stru - SP_CPORT_MASK(val), - __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2)); - -+ for (i = 0; i < eth->soc->num_ppe; i++) -+ airoha_ppe_set_cpu_port(port, i, AIROHA_GDM2_IDX); -+ - if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) { - u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq); - -@@ -1835,7 +1838,8 @@ static int airoha_dev_init(struct net_de - } - - for (i = 0; i < eth->soc->num_ppe; i++) -- airoha_ppe_set_cpu_port(port, i); -+ airoha_ppe_set_cpu_port(port, i, -+ airoha_get_fe_port(port)); - - return 0; - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -653,7 +653,8 @@ int airoha_get_fe_port(struct airoha_gdm - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); - --void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id); -+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, -+ u8 fport); - bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); - void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, - u16 hash, bool rx_wlan); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -85,10 +85,9 @@ static u32 airoha_ppe_get_timestamp(stru - return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); - } - --void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id) -+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport) - { - struct airoha_qdma *qdma = port->qdma; -- u8 fport = airoha_get_fe_port(port); - struct airoha_eth *eth = qdma->eth; - u8 qdma_id = qdma - ð->qdma[0]; - u32 fe_cpu_port; -@@ -182,7 +181,8 @@ static void airoha_ppe_hw_init(struct ai - if (!port) - continue; - -- airoha_ppe_set_cpu_port(port, i); -+ airoha_ppe_set_cpu_port(port, i, -+ airoha_get_fe_port(port)); - } - } - } diff --git a/target/linux/airoha/patches-6.12/148-v7.1-net-airoha-Fix-possible-TX-queue-stall-in-airoha_qdm.patch b/target/linux/airoha/patches-6.12/148-v7.1-net-airoha-Fix-possible-TX-queue-stall-in-airoha_qdm.patch deleted file mode 100644 index fa0d9064ef2..00000000000 --- a/target/linux/airoha/patches-6.12/148-v7.1-net-airoha-Fix-possible-TX-queue-stall-in-airoha_qdm.patch +++ /dev/null @@ -1,104 +0,0 @@ -From b94769eb2f30e61e86cd8551c084c34134290d89 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 16 Apr 2026 12:30:12 +0200 -Subject: [PATCH] net: airoha: Fix possible TX queue stall in - airoha_qdma_tx_napi_poll() - -Since multiple net_device TX queues can share the same hw QDMA TX queue, -there is no guarantee we have inflight packets queued in hw belonging to a -net_device TX queue stopped in the xmit path because hw QDMA TX queue -can be full. In this corner case the net_device TX queue will never be -re-activated. In order to avoid any potential net_device TX queue stall, -we need to wake all the net_device TX queues feeding the same hw QDMA TX -queue in airoha_qdma_tx_napi_poll routine. - -Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://patch.msgid.link/20260416-airoha-txq-potential-stall-v2-1-42c732074540@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 37 ++++++++++++++++++++---- - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - 2 files changed, 33 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -843,6 +843,21 @@ static int airoha_qdma_init_rx(struct ai - return 0; - } - -+static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q) -+{ -+ struct airoha_qdma *qdma = q->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *port = eth->ports[i]; -+ -+ if (port && port->qdma == qdma) -+ netif_tx_wake_all_queues(port->dev); -+ } -+ q->txq_stopped = false; -+} -+ - static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget) - { - struct airoha_tx_irq_queue *irq_q; -@@ -919,12 +934,21 @@ static int airoha_qdma_tx_napi_poll(stru - - txq = netdev_get_tx_queue(skb->dev, queue); - netdev_tx_completed_queue(txq, 1, skb->len); -- if (netif_tx_queue_stopped(txq) && -- q->ndesc - q->queued >= q->free_thr) -- netif_tx_wake_queue(txq); -- - dev_kfree_skb_any(skb); - } -+ -+ if (q->txq_stopped && q->ndesc - q->queued >= q->free_thr) { -+ /* Since multiple net_device TX queues can share the -+ * same hw QDMA TX queue, there is no guarantee we have -+ * inflight packets queued in hw belonging to a -+ * net_device TX queue stopped in the xmit path. -+ * In order to avoid any potential net_device TX queue -+ * stall, we need to wake all the net_device TX queues -+ * feeding the same hw QDMA TX queue. -+ */ -+ airoha_qdma_wake_netdev_txqs(q); -+ } -+ - unlock: - spin_unlock_bh(&q->lock); - } -@@ -2016,6 +2040,7 @@ static netdev_tx_t airoha_dev_xmit(struc - if (q->queued + nr_frags >= q->ndesc) { - /* not enough space in the queue */ - netif_tx_stop_queue(txq); -+ q->txq_stopped = true; - spin_unlock_bh(&q->lock); - return NETDEV_TX_BUSY; - } -@@ -2071,8 +2096,10 @@ static netdev_tx_t airoha_dev_xmit(struc - TX_RING_CPU_IDX_MASK, - FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); - -- if (q->ndesc - q->queued < q->free_thr) -+ if (q->ndesc - q->queued < q->free_thr) { - netif_tx_stop_queue(txq); -+ q->txq_stopped = true; -+ } - - spin_unlock_bh(&q->lock); - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -193,6 +193,7 @@ struct airoha_queue { - int ndesc; - int free_thr; - int buf_size; -+ bool txq_stopped; - - struct napi_struct napi; - struct page_pool *page_pool; diff --git a/target/linux/airoha/patches-6.12/150-v7.1-net-airoha-Add-size-check-for-TX-NAPIs-in-airoha_qdm.patch b/target/linux/airoha/patches-6.12/150-v7.1-net-airoha-Add-size-check-for-TX-NAPIs-in-airoha_qdm.patch deleted file mode 100644 index ea5adb1b1b7..00000000000 --- a/target/linux/airoha/patches-6.12/150-v7.1-net-airoha-Add-size-check-for-TX-NAPIs-in-airoha_qdm.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 4b91cb65789b794bfc8d50554b8994f8e0f16309 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 20 Apr 2026 10:07:48 +0200 -Subject: [PATCH] net: airoha: Add size check for TX NAPIs in - airoha_qdma_cleanup() - -If airoha_qdma_init routine fails before airoha_qdma_tx_irq_init() runs -successfully for all TX NAPIs, airoha_qdma_cleanup() will -unconditionally runs netif_napi_del() on TX NAPIs, triggering a NULL -pointer dereference. Fix the issue relying on q_tx_irq size value to -check if the TX NAPIs is properly initialized in airoha_qdma_cleanup(). -Moreover, run netif_napi_add_tx() just if irq_q queue is properly -allocated. - -Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260420-airoha_qdma_init_rx_queue-fix-v2-2-d99347e5c18d@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/airoha/airoha_eth.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1020,8 +1020,6 @@ static int airoha_qdma_tx_irq_init(struc - struct airoha_eth *eth = qdma->eth; - dma_addr_t dma_addr; - -- netif_napi_add_tx(eth->napi_dev, &irq_q->napi, -- airoha_qdma_tx_napi_poll); - irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32), - &dma_addr, GFP_KERNEL); - if (!irq_q->q) -@@ -1031,6 +1029,9 @@ static int airoha_qdma_tx_irq_init(struc - irq_q->size = size; - irq_q->qdma = qdma; - -+ netif_napi_add_tx(eth->napi_dev, &irq_q->napi, -+ airoha_qdma_tx_napi_poll); -+ - airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr); - airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK, - FIELD_PREP(TX_IRQ_DEPTH_MASK, size)); -@@ -1450,8 +1451,12 @@ static void airoha_qdma_cleanup(struct a - } - } - -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) -+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) { -+ if (!qdma->q_tx_irq[i].size) -+ continue; -+ - netif_napi_del(&qdma->q_tx_irq[i].napi); -+ } - - for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) { - if (!qdma->q_tx[i].ndesc) diff --git a/target/linux/airoha/patches-6.12/151-v7.1-net-airoha-fix-BQL-imbalance-in-TX-path.patch b/target/linux/airoha/patches-6.12/151-v7.1-net-airoha-fix-BQL-imbalance-in-TX-path.patch deleted file mode 100644 index 81286079139..00000000000 --- a/target/linux/airoha/patches-6.12/151-v7.1-net-airoha-fix-BQL-imbalance-in-TX-path.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 2d9f5a118205da2683ffcec78b9347f1f01a820e Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 21 Apr 2026 08:35:11 +0200 -Subject: [PATCH] net: airoha: fix BQL imbalance in TX path - -Fix a possible BQL imbalance in airoha_dev_xmit(), where inflight -packets are accounted only for the AIROHA_NUM_TX_RING netdev TX -queues. The queue index is computed as: - - qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx) - txq = netdev_get_tx_queue(dev, qid); - -However, airoha_qdma_tx_napi_poll() accounts completions across all -netdev TX queues (num_tx_queues), leading to inconsistent BQL -accounting. - -Also reset all netdev TX queues in the ndo_stop callback. - -Fixes: 1d304174106c ("net: airoha: Implement BQL support") -Fixes: c9f947769b77 ("net: airoha: Reset BQL stopping the netdevice") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260421-airoha-fix-bql-v1-1-f135afe4275b@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -929,10 +929,9 @@ static int airoha_qdma_tx_napi_poll(stru - q->queued--; - - if (skb) { -- u16 queue = skb_get_queue_mapping(skb); - struct netdev_queue *txq; - -- txq = netdev_get_tx_queue(skb->dev, queue); -+ txq = skb_get_tx_queue(skb->dev, skb); - netdev_tx_completed_queue(txq, 1, skb->len); - dev_kfree_skb_any(skb); - } -@@ -1744,7 +1743,7 @@ static int airoha_dev_stop(struct net_de - if (err) - return err; - -- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) -+ for (i = 0; i < dev->num_tx_queues; i++) - netdev_tx_reset_subqueue(dev, i); - - airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id), -@@ -2039,7 +2038,7 @@ static netdev_tx_t airoha_dev_xmit(struc - - spin_lock_bh(&q->lock); - -- txq = netdev_get_tx_queue(dev, qid); -+ txq = skb_get_tx_queue(dev, skb); - nr_frags = 1 + skb_shinfo(skb)->nr_frags; - - if (q->queued + nr_frags >= q->ndesc) { diff --git a/target/linux/airoha/patches-6.12/152-v7.1-net-airoha-stop-net_device-TX-queue-before-updating-.patch b/target/linux/airoha/patches-6.12/152-v7.1-net-airoha-stop-net_device-TX-queue-before-updating-.patch deleted file mode 100644 index f8a031e0d40..00000000000 --- a/target/linux/airoha/patches-6.12/152-v7.1-net-airoha-stop-net_device-TX-queue-before-updating-.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 3854de7b38be742cf7558476956d12414cb274f2 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 21 Apr 2026 08:43:07 +0200 -Subject: [PATCH] net: airoha: stop net_device TX queue before updating CPU - index - -Currently, airoha_eth driver updates the CPU index register prior of -verifying whether the number of free descriptors has fallen below the -threshold. -Move net_device TX queue length check before updating the TX CPU index -in order to update TX CPU index even if there are more packets to be -transmitted but the net_device TX queue is going to be stopped -accounting the inflight packets. - -Fixes: 1d304174106c ("net: airoha: Implement BQL support") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260421-airoha-xmit-stop-condition-v1-1-e670d6a48467@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2094,17 +2094,16 @@ static netdev_tx_t airoha_dev_xmit(struc - - skb_tx_timestamp(skb); - netdev_tx_sent_queue(txq, skb->len); -+ if (q->ndesc - q->queued < q->free_thr) { -+ netif_tx_stop_queue(txq); -+ q->txq_stopped = true; -+ } - - if (netif_xmit_stopped(txq) || !netdev_xmit_more()) - airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), - TX_RING_CPU_IDX_MASK, - FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); - -- if (q->ndesc - q->queued < q->free_thr) { -- netif_tx_stop_queue(txq); -- q->txq_stopped = true; -- } -- - spin_unlock_bh(&q->lock); - - return NETDEV_TX_OK; diff --git a/target/linux/airoha/patches-6.12/153-v7.1-net-airoha-Do-not-wake-all-netdev-TX-queues-in-airoh.patch b/target/linux/airoha/patches-6.12/153-v7.1-net-airoha-Do-not-wake-all-netdev-TX-queues-in-airoh.patch deleted file mode 100644 index 28a9e26e95b..00000000000 --- a/target/linux/airoha/patches-6.12/153-v7.1-net-airoha-Do-not-wake-all-netdev-TX-queues-in-airoh.patch +++ /dev/null @@ -1,75 +0,0 @@ -From e070aac63b42bf81f4dc565f9f841ff47e6c992f Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 21 Apr 2026 10:53:33 +0200 -Subject: [PATCH] net: airoha: Do not wake all netdev TX queues in - airoha_qdma_wake_netdev_txqs() - -Do not wake every netdev TX queue across all ports sharing the QDMA -running netif_tx_wake_all_queues routine in airoha_qdma_wake_netdev_txqs() -but only the ones that are mapped the specific QDMA stopped hw TX queue. -This patch can potentially avoid waking already stopped netdev TX queues -that are mapped to a different QDMA hw TX queue. -Introduce airoha_qdma_get_txq utility routine. - -Fixes: b94769eb2f30 ("net: airoha: Fix possible TX queue stall in airoha_qdma_tx_napi_poll()") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260421-airoha-wake_netdev_txqs-optmization-v1-1-e0be95115d53@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 19 +++++++++++++++---- - drivers/net/ethernet/airoha/airoha_eth.h | 5 +++++ - 2 files changed, 20 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -847,13 +847,24 @@ static void airoha_qdma_wake_netdev_txqs - { - struct airoha_qdma *qdma = q->qdma; - struct airoha_eth *eth = qdma->eth; -- int i; -+ int i, qid = q - &qdma->q_tx[0]; - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -+ int j; - -- if (port && port->qdma == qdma) -- netif_tx_wake_all_queues(port->dev); -+ if (!port) -+ continue; -+ -+ if (port->qdma != qdma) -+ continue; -+ -+ for (j = 0; j < port->dev->num_tx_queues; j++) { -+ if (airoha_qdma_get_txq(qdma, j) != qid) -+ continue; -+ -+ netif_wake_subqueue(port->dev, j); -+ } - } - q->txq_stopped = false; - } -@@ -2001,7 +2012,7 @@ static netdev_tx_t airoha_dev_xmit(struc - u16 index; - u8 fport; - -- qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); -+ qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb)); - tag = airoha_get_dsa_tag(skb, dev); - - msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -631,6 +631,11 @@ u32 airoha_rmw(void __iomem *base, u32 o - #define airoha_qdma_clear(qdma, offset, val) \ - airoha_rmw((qdma)->regs, (offset), (val), 0) - -+static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid) -+{ -+ return qid % ARRAY_SIZE(qdma->q_tx); -+} -+ - static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port) - { - /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. diff --git a/target/linux/airoha/patches-6.12/154-v7.1-net-airoha-Do-not-read-uninitialized-fragment-addres.patch b/target/linux/airoha/patches-6.12/154-v7.1-net-airoha-Do-not-read-uninitialized-fragment-addres.patch deleted file mode 100644 index 0980e5d31c5..00000000000 --- a/target/linux/airoha/patches-6.12/154-v7.1-net-airoha-Do-not-read-uninitialized-fragment-addres.patch +++ /dev/null @@ -1,64 +0,0 @@ -From bde34e84edc8b5571fbde7e941e175a4293ee1eb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 24 Apr 2026 11:00:28 +0200 -Subject: [PATCH] net: airoha: Do not read uninitialized fragment address in - airoha_dev_xmit() - -The transmit loop in airoha_dev_xmit() reads fragment address and length -during its final iteration, when the loop index equals -skb_shinfo(skb)->nr_frags, at which point the fragment data is -uninitialized. While these values are never consumed, the read itself is -unsafe and may trigger a page fault. Fix this by avoiding the fragment -read on the last iteration. -Additionally, move the skb pointer from the first to the last used packet -descriptor, so that airoha_qdma_tx_napi_poll() defers freeing the skb -until the final descriptor is processed. - -Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260424-airoha-xmit-fix-read-frag-v1-1-fdc0a83c79e8@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2007,8 +2007,8 @@ static netdev_tx_t airoha_dev_xmit(struc - struct netdev_queue *txq; - struct airoha_queue *q; - LIST_HEAD(tx_list); -+ int i = 0, qid; - void *data; -- int i, qid; - u16 index; - u8 fport; - -@@ -2067,7 +2067,7 @@ static netdev_tx_t airoha_dev_xmit(struc - list); - index = e - q->entry; - -- for (i = 0; i < nr_frags; i++) { -+ while (true) { - struct airoha_qdma_desc *desc = &q->desc[index]; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - dma_addr_t addr; -@@ -2079,7 +2079,7 @@ static netdev_tx_t airoha_dev_xmit(struc - goto error_unmap; - - list_move_tail(&e->list, &tx_list); -- e->skb = i ? NULL : skb; -+ e->skb = i == nr_frags - 1 ? skb : NULL; - e->dma_addr = addr; - e->dma_len = len; - -@@ -2098,6 +2098,9 @@ static netdev_tx_t airoha_dev_xmit(struc - WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); - WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); - -+ if (++i == nr_frags) -+ break; -+ - data = skb_frag_address(frag); - len = skb_frag_size(frag); - } diff --git a/target/linux/airoha/patches-6.12/155-v7.2-net-airoha-Rename-get_src_port_id-callback-in-get_sp.patch b/target/linux/airoha/patches-6.12/155-v7.2-net-airoha-Rename-get_src_port_id-callback-in-get_sp.patch deleted file mode 100644 index 425ee19eef9..00000000000 --- a/target/linux/airoha/patches-6.12/155-v7.2-net-airoha-Rename-get_src_port_id-callback-in-get_sp.patch +++ /dev/null @@ -1,75 +0,0 @@ -From c06a2f2903f6fba0a3088ad05fc5cf61a66e5d89 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 28 Apr 2026 07:23:38 +0200 -Subject: [PATCH] net: airoha: Rename get_src_port_id callback in get_sport - -For code consistency, rename get_src_port_id callback in get_sport. -Please note this patch does not introduce any logical change and it is -just a cosmetic patch. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260428-airoha-get_src_port_id-callback-v1-1-3f765c91c1e8@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 10 +++++----- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - 2 files changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1823,7 +1823,7 @@ static int airoha_set_gdm2_loopback(stru - airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); - airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX)); - -- src_port = eth->soc->ops.get_src_port_id(port, port->nbq); -+ src_port = eth->soc->ops.get_sport(port, port->nbq); - if (src_port < 0) - return src_port; - -@@ -3199,7 +3199,7 @@ static const char * const en7581_xsi_rst - "xfp-mac", - }; - --static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) -+static int airoha_en7581_get_sport(struct airoha_gdm_port *port, int nbq) - { - switch (port->id) { - case AIROHA_GDM3_IDX: -@@ -3252,7 +3252,7 @@ static const char * const an7583_xsi_rst - "xfp-mac", - }; - --static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq) -+static int airoha_an7583_get_sport(struct airoha_gdm_port *port, int nbq) - { - switch (port->id) { - case AIROHA_GDM3_IDX: -@@ -3300,7 +3300,7 @@ static const struct airoha_eth_soc_data - .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), - .num_ppe = 2, - .ops = { -- .get_src_port_id = airoha_en7581_get_src_port_id, -+ .get_sport = airoha_en7581_get_sport, - .get_vip_port = airoha_en7581_get_vip_port, - }, - }; -@@ -3311,7 +3311,7 @@ static const struct airoha_eth_soc_data - .num_xsi_rsts = ARRAY_SIZE(an7583_xsi_rsts_names), - .num_ppe = 1, - .ops = { -- .get_src_port_id = airoha_an7583_get_src_port_id, -+ .get_sport = airoha_an7583_get_sport, - .get_vip_port = airoha_an7583_get_vip_port, - }, - }; ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -578,7 +578,7 @@ struct airoha_eth_soc_data { - int num_xsi_rsts; - int num_ppe; - struct { -- int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq); -+ int (*get_sport)(struct airoha_gdm_port *port, int nbq); - u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq); - } ops; - }; diff --git a/target/linux/airoha/patches-6.12/156-v7.2-net-airoha-Do-not-return-err-in-ndo_stop-callback.patch b/target/linux/airoha/patches-6.12/156-v7.2-net-airoha-Do-not-return-err-in-ndo_stop-callback.patch deleted file mode 100644 index a111990b22c..00000000000 --- a/target/linux/airoha/patches-6.12/156-v7.2-net-airoha-Do-not-return-err-in-ndo_stop-callback.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 4ca01292ea2f2363660610a65ba0285d7c3309ed Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 28 Apr 2026 08:53:16 +0200 -Subject: [PATCH] net: airoha: Do not return err in ndo_stop() callback - -Always complete the airoha_dev_stop() routine regardless of the -airoha_set_vip_for_gdm_port() return value, since errors from -ndo_stop() are ignored by the networking stack and the interface is -always considered down after the call. - -Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260428-airoha-ndo-stop-not-err-v1-1-674506d29a91@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1747,13 +1747,10 @@ static int airoha_dev_stop(struct net_de - { - struct airoha_gdm_port *port = netdev_priv(dev); - struct airoha_qdma *qdma = port->qdma; -- int i, err; -+ int i; - - netif_tx_disable(dev); -- err = airoha_set_vip_for_gdm_port(port, false); -- if (err) -- return err; -- -+ airoha_set_vip_for_gdm_port(port, false); - for (i = 0; i < dev->num_tx_queues; i++) - netdev_tx_reset_subqueue(dev, i); - diff --git a/target/linux/airoha/patches-6.12/157-v7.2-net-airoha-Move-entries-to-queue-head-in-case-of-DMA.patch b/target/linux/airoha/patches-6.12/157-v7.2-net-airoha-Move-entries-to-queue-head-in-case-of-DMA.patch deleted file mode 100644 index 45d1a1932be..00000000000 --- a/target/linux/airoha/patches-6.12/157-v7.2-net-airoha-Move-entries-to-queue-head-in-case-of-DMA.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 75df490c9e8457990c8b227650f6491218ce018b Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 29 Apr 2026 14:02:31 +0200 -Subject: [PATCH] net: airoha: Move entries to queue head in case of DMA - mapping failure in airoha_dev_xmit() - -In order to respect the original descriptor order and avoid any -potential IOMMU fault or memory corruption, move pending queue entries -to the head of hw queue tx_list if the DMA mapping of current inflight -packet fails in airoha_dev_xmit routine. - -Fixes: 3f47e67dff1f7 ("net: airoha: Add the capability to consume out-of-order DMA tx descriptors") -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260429-airoha-xmit-unmap-error-path-v2-1-32e43b7c6d25@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2120,14 +2120,12 @@ static netdev_tx_t airoha_dev_xmit(struc - return NETDEV_TX_OK; - - error_unmap: -- while (!list_empty(&tx_list)) { -- e = list_first_entry(&tx_list, struct airoha_queue_entry, -- list); -+ list_for_each_entry(e, &tx_list, list) { - dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len, - DMA_TO_DEVICE); - e->dma_addr = 0; -- list_move_tail(&e->list, &q->tx_list); - } -+ list_splice(&tx_list, &q->tx_list); - - spin_unlock_bh(&q->lock); - error: diff --git a/target/linux/airoha/patches-6.12/158-v7.2-net-airoha-configure-QoS-channel-for-HW-accelerated-.patch b/target/linux/airoha/patches-6.12/158-v7.2-net-airoha-configure-QoS-channel-for-HW-accelerated-.patch deleted file mode 100644 index c9a6192110d..00000000000 --- a/target/linux/airoha/patches-6.12/158-v7.2-net-airoha-configure-QoS-channel-for-HW-accelerated-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 286efd34d1a1ef5d83f9441b5e59421a26738169 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 30 Apr 2026 10:47:38 +0200 -Subject: [PATCH] net: airoha: configure QoS channel for HW accelerated - flowtable traffic - -As done for the SW path, configure the QoS channel for HW accelerated -traffic according to the user port index when forwarding to a DSA port, -or rely on the GDM port identifier otherwise. This allows HTB shaping -to be applied to HW accelerated traffic. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260430-airoha-ppe-qos-channel-v1-1-5ef9221e85c1@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -332,7 +332,7 @@ static int airoha_ppe_foe_entry_prepare( - info.wcid); - } else { - struct airoha_gdm_port *port = netdev_priv(dev); -- u8 pse_port; -+ u8 pse_port, channel; - - if (!airoha_is_valid_gdm_port(eth, port)) - return -EINVAL; -@@ -345,6 +345,14 @@ static int airoha_ppe_foe_entry_prepare( - * loopback - */ - -+ /* For traffic forwarded to DSA devices select QoS -+ * channel according to the DSA user port index, rely -+ * on port id otherwise. -+ */ -+ channel = dsa_port >= 0 ? dsa_port : port->id; -+ channel = channel % AIROHA_NUM_QOS_CHANNELS; -+ qdata |= FIELD_PREP(AIROHA_FOE_CHANNEL, channel); -+ - val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port) | - AIROHA_FOE_IB2_PSE_QOS; - /* For downlink traffic consume SRAM memory for hw diff --git a/target/linux/airoha/patches-6.12/159-v7.2-net-airoha-Introduce-airoha_fe_get-airoha_qdma_get-r.patch b/target/linux/airoha/patches-6.12/159-v7.2-net-airoha-Introduce-airoha_fe_get-airoha_qdma_get-r.patch deleted file mode 100644 index ad5dcc97b99..00000000000 --- a/target/linux/airoha/patches-6.12/159-v7.2-net-airoha-Introduce-airoha_fe_get-airoha_qdma_get-r.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 98e490930de3af9afa0bbb2d1d79d6d5b5513012 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 1 May 2026 09:49:11 +0200 -Subject: [PATCH] net: airoha: Introduce airoha_fe_get()/airoha_qdma_get() - register read helpers - -Add airoha_fe_get() and airoha_qdma_get() as utility routines for reading -a masked field from a specified register. -This is a non-functional refactor, no logical changes are introduced to -the existing codebase. - -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260501-airoha_fe_get-airoha_qdma_get-v3-1-126c6f647ccb@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 13 ++++--------- - drivers/net/ethernet/airoha/airoha_eth.h | 4 ++++ - drivers/net/ethernet/airoha/airoha_ppe.c | 5 ++--- - 3 files changed, 10 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -201,15 +201,13 @@ static void airoha_fe_vip_setup(struct a - static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth, - u32 port, u32 queue) - { -- u32 val; -- - airoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR, - PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK, - FIELD_PREP(PSE_CFG_PORT_ID_MASK, port) | - FIELD_PREP(PSE_CFG_QUEUE_ID_MASK, queue)); -- val = airoha_fe_rr(eth, REG_FE_PSE_QUEUE_CFG_VAL); - -- return FIELD_GET(PSE_CFG_OQ_RSV_MASK, val); -+ return airoha_fe_get(eth, REG_FE_PSE_QUEUE_CFG_VAL, -+ PSE_CFG_OQ_RSV_MASK); - } - - static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth, -@@ -227,9 +225,7 @@ static void airoha_fe_set_pse_queue_rsv_ - - static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth) - { -- u32 val = airoha_fe_rr(eth, REG_FE_PSE_BUF_SET); -- -- return FIELD_GET(PSE_ALLRSV_MASK, val); -+ return airoha_fe_get(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK); - } - - static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth, -@@ -247,8 +243,7 @@ static int airoha_fe_set_pse_oq_rsv(stru - FIELD_PREP(PSE_ALLRSV_MASK, all_rsv)); - - /* modify hthd */ -- tmp = airoha_fe_rr(eth, PSE_FQ_CFG); -- fq_limit = FIELD_GET(PSE_FQ_LIMIT_MASK, tmp); -+ fq_limit = airoha_fe_get(eth, PSE_FQ_CFG, PSE_FQ_LIMIT_MASK); - tmp = fq_limit - all_rsv - 0x20; - airoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD, - PSE_SHARE_USED_HTHD_MASK, ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -619,6 +619,8 @@ u32 airoha_rmw(void __iomem *base, u32 o - airoha_rmw((eth)->fe_regs, (offset), 0, (val)) - #define airoha_fe_clear(eth, offset, val) \ - airoha_rmw((eth)->fe_regs, (offset), (val), 0) -+#define airoha_fe_get(eth, offset, mask) \ -+ FIELD_GET((mask), airoha_fe_rr((eth), (offset))) - - #define airoha_qdma_rr(qdma, offset) \ - airoha_rr((qdma)->regs, (offset)) -@@ -630,6 +632,8 @@ u32 airoha_rmw(void __iomem *base, u32 o - airoha_rmw((qdma)->regs, (offset), 0, (val)) - #define airoha_qdma_clear(qdma, offset, val) \ - airoha_rmw((qdma)->regs, (offset), (val), 0) -+#define airoha_qdma_get(qdma, offset, mask) \ -+ FIELD_GET((mask), airoha_qdma_rr((qdma), (offset))) - - static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid) - { ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -80,9 +80,8 @@ bool airoha_ppe_is_enabled(struct airoha - - static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe) - { -- u16 timestamp = airoha_fe_rr(ppe->eth, REG_FE_FOE_TS); -- -- return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp); -+ return airoha_fe_get(ppe->eth, REG_FE_FOE_TS, -+ AIROHA_FOE_IB1_BIND_TIMESTAMP); - } - - void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport) diff --git a/target/linux/airoha/patches-6.12/160-v7.2-net-airoha-Reserve-RX-headroom-to-avoid-skb-realloca.patch b/target/linux/airoha/patches-6.12/160-v7.2-net-airoha-Reserve-RX-headroom-to-avoid-skb-realloca.patch deleted file mode 100644 index 06d64438515..00000000000 --- a/target/linux/airoha/patches-6.12/160-v7.2-net-airoha-Reserve-RX-headroom-to-avoid-skb-realloca.patch +++ /dev/null @@ -1,73 +0,0 @@ -From bbfb1983944f2eaa8ee192e0f7b59ecc0fda9981 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 13 May 2026 17:03:59 +0200 -Subject: [PATCH] net: airoha: Reserve RX headroom to avoid skb reallocation - -Reserve NET_SKB_PAD + NET_IP_ALIGN bytes of headroom for received packets -to avoid skb head reallocation when pushing protocol headers into the skb. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260513-airoha-rx-headroom-v1-1-bd87798e422d@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 14 ++++++++------ - drivers/net/ethernet/airoha/airoha_eth.h | 2 ++ - 2 files changed, 10 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -543,9 +543,10 @@ static int airoha_qdma_fill_rx_queue(str - q->queued++; - nframes++; - -+ offset += AIROHA_RX_HEADROOM; - e->buf = page_address(page) + offset; - e->dma_addr = page_pool_get_dma_addr(page) + offset; -- e->dma_len = SKB_WITH_OVERHEAD(q->buf_size); -+ e->dma_len = SKB_WITH_OVERHEAD(AIROHA_RX_LEN(q->buf_size)); - - val = FIELD_PREP(QDMA_DESC_LEN_MASK, e->dma_len); - WRITE_ONCE(desc->ctrl, cpu_to_le32(val)); -@@ -611,13 +612,12 @@ static int airoha_qdma_rx_process(struct - q->tail = (q->tail + 1) % q->ndesc; - q->queued--; - -- dma_sync_single_for_cpu(eth->dev, e->dma_addr, -- SKB_WITH_OVERHEAD(q->buf_size), dir); -+ dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len, -+ dir); - - page = virt_to_head_page(e->buf); - len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); -- data_len = q->skb ? q->buf_size -- : SKB_WITH_OVERHEAD(q->buf_size); -+ data_len = q->skb ? AIROHA_RX_LEN(q->buf_size) : e->dma_len; - if (!len || data_len < len) - goto free_frag; - -@@ -627,10 +627,12 @@ static int airoha_qdma_rx_process(struct - - port = eth->ports[p]; - if (!q->skb) { /* first buffer */ -- q->skb = napi_build_skb(e->buf, q->buf_size); -+ q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM, -+ q->buf_size); - if (!q->skb) - goto free_frag; - -+ skb_reserve(q->skb, AIROHA_RX_HEADROOM); - __skb_put(q->skb, len); - skb_mark_for_recycle(q->skb); - q->skb->dev = port->dev; ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -32,6 +32,8 @@ - #define AIROHA_FE_MC_MAX_VLAN_TABLE 64 - #define AIROHA_FE_MC_MAX_VLAN_PORT 16 - #define AIROHA_NUM_TX_IRQ 2 -+#define AIROHA_RX_HEADROOM (NET_SKB_PAD + NET_IP_ALIGN) -+#define AIROHA_RX_LEN(_n) ((_n) - AIROHA_RX_HEADROOM) - #define HW_DSCP_NUM 2048 - #define IRQ_QUEUE_LEN(_n) ((_n) ? 1024 : 2048) - #define TX_DSCP_NUM 1024 diff --git a/target/linux/airoha/patches-6.12/161-v7.2-net-airoha-Disable-GDM2-forwarding-before-configurin.patch b/target/linux/airoha/patches-6.12/161-v7.2-net-airoha-Disable-GDM2-forwarding-before-configurin.patch deleted file mode 100644 index a6c9e9eef3f..00000000000 --- a/target/linux/airoha/patches-6.12/161-v7.2-net-airoha-Disable-GDM2-forwarding-before-configurin.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 985d4a55e64e43bd86eeb896b81ceba453301989 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 20 May 2026 15:12:02 +0200 -Subject: [PATCH] net: airoha: Disable GDM2 forwarding before configuring GDM2 - loopback - -Hw design requires to disable GDM2 forwarding before configuring GDM2 -loopback in airoha_set_gdm2_loopback routine. - -Fixes: 9cd451d414f6e ("net: airoha: Add loopback support for GDM2") -Tested-by: Madhur Agrawal -Signed-off-by: Lorenzo Bianconi -Link: https://patch.msgid.link/20260520-airoha-disable-gdm2-fwd-v1-1-1eeea5dffc2f@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/airoha/airoha_eth.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1790,11 +1790,8 @@ static int airoha_set_gdm2_loopback(stru - u32 val, pse_port, chan; - int i, src_port; - -- /* Forward the traffic to the proper GDM port */ -- pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 -- : FE_PSE_PORT_GDM4; - airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), -- pse_port); -+ FE_PSE_PORT_DROP); - airoha_fe_clear(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), - GDM_STRIP_CRC_MASK); - -@@ -1812,6 +1809,11 @@ static int airoha_set_gdm2_loopback(stru - GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, - FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | - FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU)); -+ /* Forward the traffic to the proper GDM port */ -+ pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 -+ : FE_PSE_PORT_GDM4; -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), -+ pse_port); - - /* Disable VIP and IFC for GDM2 */ - airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); diff --git a/target/linux/airoha/patches-6.12/200-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch b/target/linux/airoha/patches-6.12/200-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch deleted file mode 100644 index 9984b531e57..00000000000 --- a/target/linux/airoha/patches-6.12/200-02-ASoC-airoha-Add-AFE-and-I2S-driver-for-Airoha-AN7581.patch +++ /dev/null @@ -1,1312 +0,0 @@ -From 131f599fd0464f8e685610d9e24dadd8fbb4ba76 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 31 Jul 2025 15:32:32 +0200 -Subject: [PATCH] ASoC: airoha: Add AFE and machine driver for Airoha AN7581 - -Add support for the Sound system present on Airoha AN7581 SoC. This is -based on the mediatek AFE drivers. - -Also add the machine driver to create an actual sound card for the AFE. - -Signed-off-by: Christian Marangi ---- - MAINTAINERS | 8 + - sound/soc/mediatek/Kconfig | 20 + - sound/soc/mediatek/Makefile | 1 + - sound/soc/mediatek/an7581/Makefile | 9 + - sound/soc/mediatek/an7581/an7581-afe-common.h | 39 ++ - sound/soc/mediatek/an7581/an7581-afe-pcm.c | 497 ++++++++++++++++++ - sound/soc/mediatek/an7581/an7581-dai-etdm.c | 407 ++++++++++++++ - sound/soc/mediatek/an7581/an7581-reg.h | 88 ++++ - sound/soc/mediatek/an7581/an7581-wm8960.c | 170 ++++++ - 9 files changed, 1239 insertions(+) - create mode 100644 sound/soc/mediatek/an7581/Makefile - create mode 100644 sound/soc/mediatek/an7581/an7581-afe-common.h - create mode 100644 sound/soc/mediatek/an7581/an7581-afe-pcm.c - create mode 100644 sound/soc/mediatek/an7581/an7581-dai-etdm.c - create mode 100644 sound/soc/mediatek/an7581/an7581-reg.h - create mode 100644 sound/soc/mediatek/an7581/an7581-wm8960.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -734,6 +734,14 @@ F: Documentation/devicetree/bindings/phy - F: drivers/phy/phy-airoha-pcie-regs.h - F: drivers/phy/phy-airoha-pcie.c - -+AIROHA SOUND DRIVER -+M: Christian Marangi -+L: linux-sound@vger.kernel.org -+S: Maintained -+F: Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml -+F: Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml -+F: sound/soc/mediatek/an7581/* -+ - AIROHA SPI SNFI DRIVER - M: Lorenzo Bianconi - M: Ray Liu ---- a/sound/soc/mediatek/Kconfig -+++ b/sound/soc/mediatek/Kconfig -@@ -3,6 +3,26 @@ config SND_SOC_MEDIATEK - tristate - select REGMAP_MMIO - -+config SND_SOC_AN7581 -+ tristate "ASoC support for Airoha AN7581 chip" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ select SND_SOC_MEDIATEK -+ help -+ This adds ASoC platform driver support for Airoha AN7581 chip -+ that can be used with other codecs. -+ Select Y if you have such device. -+ If unsure select "N". -+ -+config SND_SOC_AN7581_WM8960 -+ tristate "ASoc Audio driver for Airoha AN7581 with WM8960 codec" -+ depends on SND_SOC_AN7581 && I2C -+ select SND_SOC_WM8960 -+ help -+ This adds support for ASoC machine driver for Airoha AN7581 -+ boards with the WM8960 codecs. -+ Select Y if you have such device. -+ If unsure select "N". -+ - config SND_SOC_MT2701 - tristate "ASoC support for Mediatek MT2701 chip" - depends on ARCH_MEDIATEK ---- a/sound/soc/mediatek/Makefile -+++ b/sound/soc/mediatek/Makefile -@@ -1,5 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0 - obj-$(CONFIG_SND_SOC_MEDIATEK) += common/ -+obj-$(CONFIG_SND_SOC_AN7581) += an7581/ - obj-$(CONFIG_SND_SOC_MT2701) += mt2701/ - obj-$(CONFIG_SND_SOC_MT6797) += mt6797/ - obj-$(CONFIG_SND_SOC_MT7986) += mt7986/ ---- /dev/null -+++ b/sound/soc/mediatek/an7581/Makefile -@@ -0,0 +1,9 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+# platform driver -+snd-soc-an7581-afe-y := \ -+ an7581-afe-pcm.o \ -+ an7581-dai-etdm.o -+ -+obj-$(CONFIG_SND_SOC_AN7581) += snd-soc-an7581-afe.o -+obj-$(CONFIG_SND_SOC_AN7581_WM8960) += an7581-wm8960.o ---- /dev/null -+++ b/sound/soc/mediatek/an7581/an7581-afe-common.h -@@ -0,0 +1,39 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * an7581-afe-common.h -- Airoha AN7581 audio driver definitions -+ */ -+ -+#ifndef _AN7581_AFE_COMMON_H_ -+#define _AN7581_AFE_COMMON_H_ -+ -+#include -+#include -+#include -+#include "../../mediatek/common/mtk-base-afe.h" -+ -+enum { -+ AN7581_MEMIF_DL1, -+ AN7581_MEMIF_UL1, -+ AN7581_MEMIF_NUM, -+ AN7581_DAI_ETDM = AN7581_MEMIF_NUM, -+ AN7581_DAI_NUM, -+}; -+ -+enum { -+ AN7581_IRQ_0, -+ AN7581_IRQ_1, -+ AN7581_IRQ_NUM, -+}; -+ -+struct an7581_afe_private { -+ /* dai */ -+ void *dai_priv[AN7581_DAI_NUM]; -+}; -+ -+unsigned int an7581_afe_rate_transform(struct device *dev, -+ unsigned int rate); -+ -+/* dai register */ -+int an7581_dai_etdm_register(struct mtk_base_afe *afe); -+ -+#endif ---- /dev/null -+++ b/sound/soc/mediatek/an7581/an7581-afe-pcm.c -@@ -0,0 +1,497 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Airoha ALSA SoC AFE platform driver for AN7581 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "an7581-afe-common.h" -+#include "an7581-reg.h" -+#include "../common/mtk-afe-platform-driver.h" -+#include "../common/mtk-afe-fe-dai.h" -+ -+enum { -+ ARH_AFE_RATE_8K = 0, -+ ARH_AFE_RATE_12K = 1, -+ ARH_AFE_RATE_16K = 2, -+ ARH_AFE_RATE_24K = 3, -+ ARH_AFE_RATE_32K = 4, -+ ARH_AFE_RATE_48K = 5, -+ ARH_AFE_RATE_96K = 6, -+ ARH_AFE_RATE_192K = 7, -+ ARH_AFE_RATE_384K = 8, -+ ARH_AFE_RATE_7K = 16, -+ ARH_AFE_RATE_11K = 17, -+ ARH_AFE_RATE_14K = 18, -+ ARH_AFE_RATE_22K = 19, -+ ARH_AFE_RATE_29K = 20, -+ ARH_AFE_RATE_44K = 21, -+ ARH_AFE_RATE_88K = 22, -+ ARH_AFE_RATE_176K = 23, -+ ARH_AFE_RATE_352K = 24, -+}; -+ -+unsigned int an7581_afe_rate_transform(struct device *dev, unsigned int rate) -+{ -+ switch (rate) { -+ case 7350: -+ return ARH_AFE_RATE_7K; -+ case 8000: -+ return ARH_AFE_RATE_8K; -+ case 11025: -+ return ARH_AFE_RATE_11K; -+ case 12000: -+ return ARH_AFE_RATE_12K; -+ case 14700: -+ return ARH_AFE_RATE_14K; -+ case 16000: -+ return ARH_AFE_RATE_16K; -+ case 22050: -+ return ARH_AFE_RATE_22K; -+ case 24000: -+ return ARH_AFE_RATE_24K; -+ case 29400: -+ return ARH_AFE_RATE_29K; -+ case 32000: -+ return ARH_AFE_RATE_32K; -+ case 44100: -+ return ARH_AFE_RATE_44K; -+ case 48000: -+ return ARH_AFE_RATE_48K; -+ case 88200: -+ return ARH_AFE_RATE_88K; -+ case 96000: -+ return ARH_AFE_RATE_96K; -+ case 176400: -+ return ARH_AFE_RATE_176K; -+ case 192000: -+ return ARH_AFE_RATE_192K; -+ case 352800: -+ return ARH_AFE_RATE_352K; -+ case 384000: -+ return ARH_AFE_RATE_384K; -+ default: -+ dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n", -+ __func__, rate, ARH_AFE_RATE_48K); -+ return ARH_AFE_RATE_48K; -+ } -+} -+ -+static const int an7581_memif_specified_irqs[AN7581_MEMIF_NUM] = { -+ [AN7581_MEMIF_DL1] = AN7581_IRQ_0, -+ [AN7581_MEMIF_UL1] = AN7581_IRQ_1, -+}; -+ -+static const struct snd_pcm_hardware an7581_afe_hardware = { -+ .info = SNDRV_PCM_INFO_MMAP | -+ SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_MMAP_VALID, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE, -+ .period_bytes_min = 512, -+ .period_bytes_max = 128 * 1024, -+ .periods_min = 2, -+ .periods_max = 256, -+ .buffer_bytes_max = 256 * 1024, -+ .fifo_size = 0, -+}; -+ -+static int an7581_memif_fs(struct snd_pcm_substream *substream, -+ unsigned int rate) -+{ -+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); -+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); -+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); -+ -+ return an7581_afe_rate_transform(afe->dev, rate); -+} -+ -+static int an7581_irq_fs(struct snd_pcm_substream *substream, -+ unsigned int rate) -+{ -+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); -+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); -+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); -+ -+ return an7581_afe_rate_transform(afe->dev, rate); -+} -+ -+#define ARH_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ -+ SNDRV_PCM_FMTBIT_S32_LE) -+ -+static struct snd_soc_dai_driver an7581_memif_dai_driver[] = { -+ /* FE DAIs: memory intefaces to CPU */ -+ { -+ .name = "DL1", -+ .id = AN7581_MEMIF_DL1, -+ .playback = { -+ .stream_name = "DL1", -+ .channels_min = 1, -+ .channels_max = 8, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = ARH_PCM_FORMATS, -+ }, -+ .ops = &mtk_afe_fe_ops, -+ }, -+ { -+ .name = "UL1", -+ .id = AN7581_MEMIF_UL1, -+ .capture = { -+ .stream_name = "UL1", -+ .channels_min = 1, -+ .channels_max = 8, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = ARH_PCM_FORMATS, -+ }, -+ .ops = &mtk_afe_fe_ops, -+ }, -+}; -+ -+static const struct snd_soc_dapm_widget an7581_memif_widgets[] = { -+ /* DL */ -+ SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0), -+ SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0), -+ -+ /* UL */ -+ SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0, NULL, 0), -+ SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0, NULL, 0), -+}; -+ -+static const struct snd_soc_dapm_route an7581_memif_routes[] = { -+ {"I032", NULL, "DL1"}, -+ {"I033", NULL, "DL1"}, -+ {"UL1", NULL, "O018"}, -+ {"UL1", NULL, "O019"}, -+ {"O018", NULL, "I150"}, -+ {"O019", NULL, "I151"}, -+}; -+ -+static const struct snd_soc_component_driver an7581_afe_pcm_dai_component = { -+ .name = "an7581-afe-pcm-dai", -+}; -+ -+static const struct mtk_base_memif_data memif_data[AN7581_MEMIF_NUM] = { -+ [AN7581_MEMIF_DL1] = { -+ .name = "DL1", -+ .id = AN7581_MEMIF_DL1, -+ .reg_ofs_base = AFE_DL1_BASE, -+ .reg_ofs_cur = AFE_DL1_CUR, -+ .reg_ofs_end = AFE_DL1_END, -+ .fs_reg = -1, -+ .fs_shift = -1, -+ .fs_maskbit = -1, -+ .mono_reg = -1, -+ .mono_shift = -1, -+ .hd_reg = AFE_DL1_CON0, -+ .hd_shift = AFE_HD_SHIFT, -+ .enable_reg = AFE_DAC_CON0, -+ .enable_shift = AFE_DL1_ENABLE_SHIFT, -+ .msb_reg = -1, -+ .msb_shift = -1, -+ .agent_disable_reg = -1, -+ .agent_disable_shift = -1, -+ .pbuf_reg = AFE_DL1_CON0, -+ .pbuf_mask = AFE_PBUF_SIZE_MASK, -+ .pbuf_shift = AFE_PBUF_SIZE_SHIFT, -+ .minlen_reg = AFE_DL1_CON0, -+ .minlen_mask = AFE_MINLEN_MASK, -+ .minlen_shift = AFE_MINLEN_SHIFT, -+ }, -+ [AN7581_MEMIF_UL1] = { -+ .name = "UL1", -+ .id = AN7581_MEMIF_UL1, -+ .reg_ofs_base = AFE_UL1_BASE, -+ .reg_ofs_cur = AFE_UL1_CUR, -+ .reg_ofs_end = AFE_UL1_END, -+ .fs_reg = -1, -+ .fs_shift = -1, -+ .fs_maskbit = -1, -+ .mono_reg = -1, -+ .mono_shift = -1, -+ .hd_reg = AFE_UL1_CON0, -+ .hd_shift = AFE_HD_SHIFT, -+ .enable_reg = AFE_DAC_CON0, -+ .enable_shift = AFE_UL1_ENABLE_SHIFT, -+ .msb_reg = AFE_UL1_CON0, -+ .msb_shift = AFE_MSB_SHIFT, -+ .agent_disable_reg = -1, -+ .agent_disable_shift = -1, -+ }, -+}; -+ -+static const struct mtk_base_irq_data irq_data[AN7581_IRQ_NUM] = { -+ [AN7581_IRQ_0] = { -+ .id = AN7581_IRQ_0, -+ .irq_cnt_reg = AFE_IRQ_CNT, -+ .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, -+ .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, -+ .irq_en_reg = AFE_IRQ_CON0, -+ .irq_en_shift = AFE_IRQ_ON_SHIFT, -+ .irq_fs_reg = -1, -+ .irq_fs_shift = -1, -+ .irq_fs_maskbit = -1, -+ .irq_clr_reg = AFE_IRQ_CON0, -+ .irq_clr_shift = AFE_IRQ_CLR_SHIFT, -+ }, -+ [AN7581_IRQ_1] = { -+ .id = AN7581_IRQ_1, -+ .irq_cnt_reg = AFE_IRQ1_CNT, -+ .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, -+ .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, -+ .irq_en_reg = AFE_IRQ1_CON0, -+ .irq_en_shift = AFE_IRQ_ON_SHIFT, -+ .irq_fs_reg = -1, -+ .irq_fs_shift = -1, -+ .irq_fs_maskbit = -1, -+ .irq_clr_reg = AFE_IRQ1_CON0, -+ .irq_clr_shift = AFE_IRQ_CLR_SHIFT, -+ }, -+}; -+ -+static const struct regmap_config an7581_afe_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = AFE_MAX_REGISTER, -+ .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1), -+}; -+ -+static irqreturn_t an7581_afe_irq_handler(int irq_id, void *dev) -+{ -+ struct mtk_base_afe *afe = dev; -+ struct mtk_base_afe_irq *irq; -+ u32 status; -+ u32 reg; -+ int i; -+ -+ regmap_read(afe->regmap, AFE_IRQ_STS, &status); -+ -+ if (status & AFE_IRQ_STS_RECORD) -+ reg = AFE_IRQ1_CON0; -+ else -+ reg = AFE_IRQ_CON0; -+ -+ regmap_set_bits(afe->regmap, reg, BIT(2)); -+ regmap_clear_bits(afe->regmap, reg, BIT(2)); -+ -+ regmap_set_bits(afe->regmap, reg, BIT(3)); -+ regmap_clear_bits(afe->regmap, reg, BIT(3)); -+ -+ for (i = 0; i < AN7581_MEMIF_NUM; i++) { -+ struct mtk_base_afe_memif *memif = &afe->memif[i]; -+ -+ if (!memif->substream) -+ continue; -+ -+ if (memif->irq_usage < 0) -+ continue; -+ -+ irq = &afe->irqs[memif->irq_usage]; -+ -+ if (status & (1 << irq->irq_data->irq_clr_shift)) -+ snd_pcm_period_elapsed(memif->substream); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int an7581_afe_runtime_suspend(struct device *dev) -+{ -+ return 0; -+} -+ -+static int an7581_afe_runtime_resume(struct device *dev) -+{ -+ return 0; -+} -+ -+static int an7581_dai_memif_register(struct mtk_base_afe *afe) -+{ -+ struct mtk_base_afe_dai *dai; -+ -+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); -+ if (!dai) -+ return -ENOMEM; -+ -+ list_add(&dai->list, &afe->sub_dais); -+ -+ dai->dai_drivers = an7581_memif_dai_driver; -+ dai->num_dai_drivers = ARRAY_SIZE(an7581_memif_dai_driver); -+ -+ dai->dapm_widgets = an7581_memif_widgets; -+ dai->num_dapm_widgets = ARRAY_SIZE(an7581_memif_widgets); -+ dai->dapm_routes = an7581_memif_routes; -+ dai->num_dapm_routes = ARRAY_SIZE(an7581_memif_routes); -+ -+ return 0; -+} -+ -+typedef int (*dai_register_cb)(struct mtk_base_afe *); -+static const dai_register_cb dai_register_cbs[] = { -+ an7581_dai_etdm_register, -+ an7581_dai_memif_register, -+}; -+ -+static int an7581_afe_pcm_dev_probe(struct platform_device *pdev) -+{ -+ struct an7581_afe_private *afe_priv; -+ struct reset_control *reset; -+ struct mtk_base_afe *afe; -+ struct device *dev; -+ int i, irq_id, ret; -+ -+ afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); -+ if (!afe) -+ return -ENOMEM; -+ platform_set_drvdata(pdev, afe); -+ -+ afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), -+ GFP_KERNEL); -+ if (!afe->platform_priv) -+ return -ENOMEM; -+ -+ afe_priv = afe->platform_priv; -+ afe->dev = &pdev->dev; -+ dev = afe->dev; -+ -+ reset = devm_reset_control_get_exclusive(dev, NULL); -+ if (IS_ERR(reset)) -+ return PTR_ERR(reset); -+ -+ /* Global reset I2S */ -+ reset_control_assert(reset); -+ usleep_range(10, 20); -+ reset_control_deassert(reset); -+ -+ afe->base_addr = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(afe->base_addr)) -+ return PTR_ERR(afe->base_addr); -+ -+ ret = devm_pm_runtime_enable(dev); -+ if (ret) -+ return ret; -+ -+ pm_runtime_get_sync(&pdev->dev); -+ -+ afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, -+ &an7581_afe_regmap_config); -+ -+ pm_runtime_put_sync(&pdev->dev); -+ if (IS_ERR(afe->regmap)) -+ return PTR_ERR(afe->regmap); -+ -+ mutex_init(&afe->irq_alloc_lock); -+ -+ /* irq initialize */ -+ afe->irqs_size = AN7581_IRQ_NUM; -+ afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), -+ GFP_KERNEL); -+ if (!afe->irqs) -+ return -ENOMEM; -+ -+ for (i = 0; i < afe->irqs_size; i++) -+ afe->irqs[i].irq_data = &irq_data[i]; -+ -+ /* request irq */ -+ irq_id = platform_get_irq(pdev, 0); -+ if (irq_id < 0) -+ return irq_id; -+ -+ ret = devm_request_irq(dev, irq_id, an7581_afe_irq_handler, -+ IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to request irq for asys-isr\n"); -+ -+ /* init memif */ -+ afe->memif_size = AN7581_MEMIF_NUM; -+ afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), -+ GFP_KERNEL); -+ if (!afe->memif) -+ return -ENOMEM; -+ -+ for (i = 0; i < afe->memif_size; i++) { -+ int sel_irq = an7581_memif_specified_irqs[i]; -+ -+ afe->memif[i].data = &memif_data[i]; -+ afe->memif[i].irq_usage = sel_irq; -+ afe->memif[i].const_irq = 1; -+ afe->irqs[sel_irq].irq_occupyed = true; -+ } -+ -+ /* init sub_dais */ -+ INIT_LIST_HEAD(&afe->sub_dais); -+ -+ for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) { -+ ret = dai_register_cbs[i](afe); -+ if (ret) -+ return dev_err_probe(dev, ret, "DAI register failed, i: %d\n", i); -+ } -+ -+ /* init dai_driver and component_driver */ -+ ret = mtk_afe_combine_sub_dai(afe); -+ if (ret) -+ return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n"); -+ -+ afe->mtk_afe_hardware = &an7581_afe_hardware; -+ afe->memif_fs = an7581_memif_fs; -+ afe->irq_fs = an7581_irq_fs; -+ -+ afe->runtime_resume = an7581_afe_runtime_resume; -+ afe->runtime_suspend = an7581_afe_runtime_suspend; -+ -+ /* register component */ -+ ret = devm_snd_soc_register_component(&pdev->dev, -+ &mtk_afe_pcm_platform, -+ NULL, 0); -+ if (ret) -+ return dev_err_probe(dev, ret, "Cannot register AFE component\n"); -+ -+ ret = devm_snd_soc_register_component(afe->dev, -+ &an7581_afe_pcm_dai_component, -+ afe->dai_drivers, -+ afe->num_dai_drivers); -+ if (ret) -+ return dev_err_probe(dev, ret, "Cannot register PCM DAI component\n"); -+ -+ return 0; -+} -+ -+static void an7581_afe_pcm_dev_remove(struct platform_device *pdev) -+{ -+ pm_runtime_disable(&pdev->dev); -+ if (!pm_runtime_status_suspended(&pdev->dev)) -+ an7581_afe_runtime_suspend(&pdev->dev); -+} -+ -+static const struct of_device_id an7581_afe_pcm_dt_match[] = { -+ { .compatible = "airoha,an7581-afe" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, an7581_afe_pcm_dt_match); -+ -+static const struct dev_pm_ops an7581_afe_pm_ops = { -+ RUNTIME_PM_OPS(an7581_afe_runtime_suspend, -+ an7581_afe_runtime_resume, NULL) -+}; -+ -+static struct platform_driver an7581_afe_pcm_driver = { -+ .driver = { -+ .name = "an7581-audio", -+ .of_match_table = an7581_afe_pcm_dt_match, -+ .pm = pm_ptr(&an7581_afe_pm_ops), -+ }, -+ .probe = an7581_afe_pcm_dev_probe, -+ .remove = an7581_afe_pcm_dev_remove, -+}; -+module_platform_driver(an7581_afe_pcm_driver); -+ -+MODULE_DESCRIPTION("Airoha SoC AFE platform driver for ALSA AN7581"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/sound/soc/mediatek/an7581/an7581-dai-etdm.c -@@ -0,0 +1,407 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Airoha ALSA SoC Audio DAI eTDM Control -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include "an7581-afe-common.h" -+#include "an7581-reg.h" -+ -+#define HOPPING_CLK 0 -+#define APLL_CLK 1 -+#define MTK_DAI_ETDM_FORMAT_I2S 0 -+#define MTK_DAI_ETDM_FORMAT_DSPA 4 -+#define MTK_DAI_ETDM_FORMAT_DSPB 5 -+ -+enum { -+ MTK_ETDM_RATE_8K = 0, -+ MTK_ETDM_RATE_12K = 1, -+ MTK_ETDM_RATE_16K = 2, -+ MTK_ETDM_RATE_24K = 3, -+ MTK_ETDM_RATE_32K = 4, -+ MTK_ETDM_RATE_48K = 5, -+ MTK_ETDM_RATE_96K = 6, -+ MTK_ETDM_RATE_192K = 7, -+ MTK_ETDM_RATE_384K = 8, -+ MTK_ETDM_RATE_7K = 16, -+ MTK_ETDM_RATE_11K = 17, -+ MTK_ETDM_RATE_14K = 18, -+ MTK_ETDM_RATE_22K = 19, -+ MTK_ETDM_RATE_29K = 20, -+ MTK_ETDM_RATE_44K = 21, -+ MTK_ETDM_RATE_88K = 22, -+ MTK_ETDM_RATE_176K = 23, -+ MTK_ETDM_RATE_352K = 24, -+}; -+ -+struct mtk_dai_etdm_priv { -+ bool bck_inv; -+ bool lrck_inv; -+ bool slave_mode; -+ unsigned int format; -+}; -+ -+static unsigned int an7581_etdm_rate_transform(struct device *dev, unsigned int rate) -+{ -+ switch (rate) { -+ case 7350: -+ return MTK_ETDM_RATE_7K; -+ case 8000: -+ return MTK_ETDM_RATE_8K; -+ case 11025: -+ return MTK_ETDM_RATE_11K; -+ case 12000: -+ return MTK_ETDM_RATE_12K; -+ case 14700: -+ return MTK_ETDM_RATE_14K; -+ case 16000: -+ return MTK_ETDM_RATE_16K; -+ case 22050: -+ return MTK_ETDM_RATE_22K; -+ case 24000: -+ return MTK_ETDM_RATE_24K; -+ case 29400: -+ return MTK_ETDM_RATE_29K; -+ case 32000: -+ return MTK_ETDM_RATE_32K; -+ case 44100: -+ return MTK_ETDM_RATE_44K; -+ case 48000: -+ return MTK_ETDM_RATE_48K; -+ case 88200: -+ return MTK_ETDM_RATE_88K; -+ case 96000: -+ return MTK_ETDM_RATE_96K; -+ case 176400: -+ return MTK_ETDM_RATE_176K; -+ case 192000: -+ return MTK_ETDM_RATE_192K; -+ case 352800: -+ return MTK_ETDM_RATE_352K; -+ case 384000: -+ return MTK_ETDM_RATE_384K; -+ default: -+ dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n", -+ __func__, rate, MTK_ETDM_RATE_48K); -+ return MTK_ETDM_RATE_48K; -+ } -+} -+ -+static int get_etdm_wlen(unsigned int bitwidth) -+{ -+ return bitwidth <= 16 ? 16 : 32; -+} -+ -+static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = { -+ /* DL */ -+ SND_SOC_DAPM_MIXER("I150", SND_SOC_NOPM, 0, 0, NULL, 0), -+ SND_SOC_DAPM_MIXER("I151", SND_SOC_NOPM, 0, 0, NULL, 0), -+ -+ /* UL */ -+ SND_SOC_DAPM_MIXER("O124", SND_SOC_NOPM, 0, 0, NULL, 0), -+ SND_SOC_DAPM_MIXER("O125", SND_SOC_NOPM, 0, 0, NULL, 0), -+}; -+ -+static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { -+ {"I150", NULL, "ETDM Capture"}, -+ {"I151", NULL, "ETDM Capture"}, -+ {"ETDM Playback", NULL, "O124"}, -+ {"ETDM Playback", NULL, "O125"}, -+ {"O124", NULL, "I032"}, -+ {"O125", NULL, "I033"}, -+}; -+ -+/* dai ops */ -+static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ return 0; -+} -+ -+static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+} -+ -+static unsigned int get_etdm_ch_fixup(unsigned int channels) -+{ -+ if (channels > 16) -+ return 24; -+ else if (channels > 8) -+ return 16; -+ else if (channels > 4) -+ return 8; -+ else if (channels > 2) -+ return 4; -+ else -+ return 2; -+} -+ -+static int mtk_dai_etdm_config(struct mtk_base_afe *afe, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai, -+ int stream) -+{ -+ struct an7581_afe_private *afe_priv = afe->platform_priv; -+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id]; -+ unsigned int rate = params_rate(params); -+ unsigned int etdm_rate = an7581_etdm_rate_transform(afe->dev, rate); -+ unsigned int channels = params_channels(params); -+ unsigned int bit_width = params_width(params); -+ unsigned int wlen = get_etdm_wlen(bit_width); -+ unsigned int val = 0; -+ unsigned int mask = 0; -+ -+ dev_dbg(afe->dev, "%s(), stream %d, rate %u, bitwidth %u\n", -+ __func__, stream, rate, bit_width); -+ -+ /* CON0 */ -+ mask |= ETDM_BIT_LEN; -+ val |= FIELD_PREP(ETDM_BIT_LEN, bit_width - 1); -+ mask |= ETDM_WRD_LEN; -+ val |= FIELD_PREP(ETDM_WRD_LEN, wlen - 1); -+ mask |= ETDM_FMT; -+ val |= FIELD_PREP(ETDM_FMT, etdm_data->format); -+ mask |= ETDM_CH_NUM; -+ val |= FIELD_PREP(ETDM_CH_NUM, get_etdm_ch_fixup(channels) - 1); -+ mask |= ETDM_MODE; -+ val |= ETDM_MODE; -+ -+ switch (stream) { -+ case SNDRV_PCM_STREAM_PLAYBACK: -+ /* set ETDM_OUT1_CON0 */ -+ regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, mask, val); -+ -+ /* set ETDM_OUT1_CON1 */ -+ regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, -+ EDTM_DIRECT_INPUT_MASTER_BCK | -+ EDTM_LRCK_AUTO_MODE | -+ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | -+ EDTM_INITIAL_POINT | EDTM_INITIAL_COUNT, -+ EDTM_DIRECT_INPUT_MASTER_BCK | -+ EDTM_LRCK_AUTO_MODE | -+ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | -+ FIELD_PREP(EDTM_INITIAL_POINT, 14) | -+ FIELD_PREP(EDTM_INITIAL_COUNT, 14)); -+ -+ /* set ETDM_OUT1_CON4 */ -+ regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, OUT_SEL_FS, -+ FIELD_PREP(OUT_SEL_FS, etdm_rate)); -+ break; -+ case SNDRV_PCM_STREAM_CAPTURE: -+ /* set ETDM_IN1_CON0 */ -+ regmap_update_bits(afe->regmap, ETDM_IN1_CON0, mask, val); -+ regmap_set_bits(afe->regmap, ETDM_IN1_CON0, ETDM_SYNC); -+ -+ /* set ETDM_IN1_CON1 */ -+ regmap_update_bits(afe->regmap, ETDM_IN1_CON1, -+ EDTM_LRCK_AUTO_MODE | -+ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | -+ EDTM_INITIAL_POINT | EDTM_INITIAL_COUNT, -+ EDTM_LRCK_AUTO_MODE | -+ EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | -+ FIELD_PREP(EDTM_INITIAL_POINT, 14) | -+ FIELD_PREP(EDTM_INITIAL_COUNT, 14)); -+ -+ /* set ETDM_IN1_CON3 */ -+ regmap_update_bits(afe->regmap, ETDM_IN1_CON3, IN_SEL_FS, -+ FIELD_PREP(IN_SEL_FS, etdm_rate)); -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ unsigned int rate = params_rate(params); -+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); -+ -+ regmap_update_bits(afe->regmap, ETDM_COWORK_CON0, -+ EDTM_IN1_SLAVE_SEL, FIELD_PREP(EDTM_IN1_SLAVE_SEL, 1)); -+ regmap_update_bits(afe->regmap, ETDM_COWORK_CON0, -+ EDTM_OUT1_SLAVE_SEL, FIELD_PREP(EDTM_OUT1_SLAVE_SEL, 1)); -+ regmap_update_bits(afe->regmap, ETDM_COWORK_CON1, -+ EDTM_IN1_SDATA0_SEL, FIELD_PREP(EDTM_IN1_SDATA0_SEL, 0)); -+ -+ switch (rate) { -+ case 8000: -+ case 12000: -+ case 16000: -+ case 24000: -+ case 32000: -+ case 48000: -+ case 96000: -+ case 192000: -+ mtk_dai_etdm_config(afe, params, dai, substream->stream); -+ return 0; -+ default: -+ dev_err(afe->dev, -+ "Sample rate %d invalid. Supported rates: 8/12/16/24/32/48/96/192 kHz\n", -+ rate); -+ return -EINVAL; -+ } -+} -+ -+static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd, -+ struct snd_soc_dai *dai) -+{ -+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); -+ -+ dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id); -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ regmap_set_bits(afe->regmap, ETDM_IN1_CON0, ETDM_EN); -+ regmap_set_bits(afe->regmap, ETDM_OUT1_CON0, ETDM_EN); -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ regmap_clear_bits(afe->regmap, ETDM_IN1_CON0, ETDM_EN); -+ regmap_clear_bits(afe->regmap, ETDM_OUT1_CON0, ETDM_EN); -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -+{ -+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); -+ struct an7581_afe_private *afe_priv = afe->platform_priv; -+ struct mtk_dai_etdm_priv *etdm_data; -+ void *priv_data; -+ -+ switch (dai->id) { -+ case AN7581_DAI_ETDM: -+ break; -+ default: -+ dev_warn(afe->dev, "%s(), id %d not support\n", -+ __func__, dai->id); -+ return -EINVAL; -+ } -+ -+ priv_data = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_etdm_priv), -+ GFP_KERNEL); -+ if (!priv_data) -+ return -ENOMEM; -+ -+ afe_priv->dai_priv[dai->id] = priv_data; -+ etdm_data = afe_priv->dai_priv[dai->id]; -+ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S; -+ break; -+ case SND_SOC_DAIFMT_DSP_A: -+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA; -+ break; -+ case SND_SOC_DAIFMT_DSP_B: -+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_NB_NF: -+ etdm_data->bck_inv = false; -+ etdm_data->lrck_inv = false; -+ break; -+ case SND_SOC_DAIFMT_NB_IF: -+ etdm_data->bck_inv = false; -+ etdm_data->lrck_inv = true; -+ break; -+ case SND_SOC_DAIFMT_IB_NF: -+ etdm_data->bck_inv = true; -+ etdm_data->lrck_inv = false; -+ break; -+ case SND_SOC_DAIFMT_IB_IF: -+ etdm_data->bck_inv = true; -+ etdm_data->lrck_inv = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBP_CFP: -+ etdm_data->slave_mode = true; -+ break; -+ case SND_SOC_DAIFMT_CBC_CFC: -+ etdm_data->slave_mode = false; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct snd_soc_dai_ops mtk_dai_etdm_ops = { -+ .startup = mtk_dai_etdm_startup, -+ .shutdown = mtk_dai_etdm_shutdown, -+ .hw_params = mtk_dai_etdm_hw_params, -+ .trigger = mtk_dai_etdm_trigger, -+ .set_fmt = mtk_dai_etdm_set_fmt, -+}; -+ -+/* dai driver */ -+#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ -+ SNDRV_PCM_FMTBIT_S24_LE |\ -+ SNDRV_PCM_FMTBIT_S32_LE) -+ -+static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = { -+ { -+ .name = "ETDM", -+ .id = AN7581_DAI_ETDM, -+ .capture = { -+ .stream_name = "ETDM Capture", -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = MTK_ETDM_FORMATS, -+ }, -+ .playback = { -+ .stream_name = "ETDM Playback", -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = MTK_ETDM_FORMATS, -+ }, -+ .ops = &mtk_dai_etdm_ops, -+ .symmetric_rate = 1, -+ .symmetric_sample_bits = 1, -+ }, -+}; -+ -+int an7581_dai_etdm_register(struct mtk_base_afe *afe) -+{ -+ struct mtk_base_afe_dai *dai; -+ -+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); -+ if (!dai) -+ return -ENOMEM; -+ -+ list_add(&dai->list, &afe->sub_dais); -+ -+ dai->dai_drivers = mtk_dai_etdm_driver; -+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver); -+ -+ dai->dapm_widgets = mtk_dai_etdm_widgets; -+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets); -+ dai->dapm_routes = mtk_dai_etdm_routes; -+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes); -+ -+ return 0; -+} ---- /dev/null -+++ b/sound/soc/mediatek/an7581/an7581-reg.h -@@ -0,0 +1,88 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * an7581-reg.h -- Airoha AN7581 audio driver reg definition -+ */ -+ -+#ifndef _AN7581_REG_H_ -+#define _AN7581_REG_H_ -+ -+#define AFE_DAC_CON0 0x0 -+#define AFE_DL1_ENABLE_SHIFT 17 -+#define AFE_UL1_ENABLE_SHIFT 1 -+ -+#define ETDM_COWORK_CON0 0x4c -+#define EDTM_IN1_SLAVE_SEL GENMASK(27, 24) -+#define EDTM_OUT1_SLAVE_SEL GENMASK(11, 8) -+#define ETDM_COWORK_CON1 0x50 -+#define EDTM_IN1_SDATA0_SEL GENMASK(3, 0) -+#define ETDM_IN1_CON0 0x5c -+#define EDTM_LRCK_AUTO_MODE BIT(29) -+#define ETDM_CH_NUM GENMASK(27, 23) -+#define ETDM_WRD_LEN GENMASK(20, 16) -+#define ETDM_BIT_LEN GENMASK(15, 11) -+#define ETDM_FMT GENMASK(8, 6) -+#define ETDM_MODE BIT(5) -+#define ETDM_SYNC BIT(1) -+#define ETDM_EN BIT(0) -+#define ETDM_IN1_CON1 0x60 -+#define ETDM_IN1_CON2 0x64 -+#define IN_CLK_SRC GENMASK(12, 10) -+#define ETDM_IN1_CON3 0x68 -+#define IN_SEL_FS GENMASK(30, 26) -+#define ETDM_IN1_CON4 0x6c -+#define IN_RELATCH GENMASK(24, 20) -+#define IN_CLK_INV BIT(18) -+#define ETDM_IN1_CON5 0x70 -+#define ETDM_IN1_CON6 0x74 -+#define ETDM_OUT1_CON0 0x7c -+#define ETDM_OUT1_CON1 0x80 -+#define EDTM_DIRECT_INPUT_MASTER_BCK BIT(30) -+#define EDTM_CKEN_SEL BIT(12) -+#define EDTM_LRCK_AUTO_OFF BIT(10) -+#define EDTM_INITIAL_POINT GENMASK(9, 5) -+#define EDTM_INITIAL_COUNT GENMASK(4, 0) -+#define ETDM_OUT1_CON2 0x84 -+#define ETDM_OUT1_CON3 0x88 -+#define ETDM_OUT1_CON4 0x8c -+#define OUT_RELATCH GENMASK(28, 24) -+#define OUT_CLK_SRC GENMASK(8, 6) -+#define OUT_SEL_FS GENMASK(4, 0) -+#define ETDM_OUT1_CON5 0x90 -+#define ETDM_CLK_DIV BIT(12) -+#define OUT_CLK_INV BIT(9) -+#define ETDM_OUT1_CON6 0x94 -+#define ETDM_OUT1_CON7 0x98 -+ -+#define AFE_DL1_BASE 0xa8 -+#define AFE_DL1_END 0xb0 -+#define AFE_DL1_CUR 0xac -+#define AFE_DL1_CON0 0xb4 -+#define AFE_PBUF_SIZE_SHIFT 16 -+#define AFE_PBUF_SIZE_MASK GENMASK(1, 0) -+#define AFE_MINLEN_SHIFT 8 -+#define AFE_MINLEN_MASK GENMASK(3, 0) -+#define AFE_HD_SHIFT 5 -+ -+#define AFE_UL1_BASE 0xc4 -+#define AFE_UL1_END 0xc8 -+#define AFE_UL1_CUR 0xcc -+#define AFE_UL1_CON0 0xd0 -+#define AFE_MSB_SHIFT 6 -+ -+#define AFE_IRQ_CON0 0xe4 -+#define AFE_IRQ_ON_SHIFT 0 -+#define AFE_IRQ_CLR_SHIFT 1 -+#define AFE_IRQ_CNT 0xe8 -+#define AFE_IRQ_CNT_SHIFT 0 -+#define AFE_IRQ_CNT_MASK GENMASK(31, 0) -+ -+#define AFE_IRQ_STS 0xf8 -+#define AFE_IRQ_STS_PLAY BIT(1) -+#define AFE_IRQ_STS_RECORD BIT(0) -+ -+#define AFE_IRQ1_CON0 0x100 -+#define AFE_IRQ1_CNT 0x104 -+ -+#define AFE_MAX_REGISTER AFE_IRQ1_CON0 -+ -+#endif ---- /dev/null -+++ b/sound/soc/mediatek/an7581/an7581-wm8960.c -@@ -0,0 +1,170 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Airoha ALSA SoC I2S platform driver for AN7581 -+ * -+ */ -+ -+#include -+#include -+ -+#include "an7581-afe-common.h" -+ -+static const struct snd_soc_dapm_widget an7581_wm8960_widgets[] = { -+ SND_SOC_DAPM_HP("Headphone", NULL), -+ SND_SOC_DAPM_MIC("AMIC", NULL), -+}; -+ -+static const struct snd_kcontrol_new an7581_wm8960_controls[] = { -+ SOC_DAPM_PIN_SWITCH("Headphone"), -+ SOC_DAPM_PIN_SWITCH("AMIC"), -+}; -+ -+SND_SOC_DAILINK_DEFS(playback, -+ DAILINK_COMP_ARRAY(COMP_CPU("DL1")), -+ DAILINK_COMP_ARRAY(COMP_DUMMY()), -+ DAILINK_COMP_ARRAY(COMP_EMPTY())); -+ -+SND_SOC_DAILINK_DEFS(capture, -+ DAILINK_COMP_ARRAY(COMP_CPU("UL1")), -+ DAILINK_COMP_ARRAY(COMP_DUMMY()), -+ DAILINK_COMP_ARRAY(COMP_EMPTY())); -+ -+SND_SOC_DAILINK_DEFS(codec, -+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM")), -+ DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")), -+ DAILINK_COMP_ARRAY(COMP_EMPTY())); -+ -+static struct snd_soc_dai_link an7581_wm8960_dai_links[] = { -+ /* FE */ -+ { -+ .name = "wm8960-playback", -+ .stream_name = "wm8960-playback", -+ .trigger = {SND_SOC_DPCM_TRIGGER_POST, -+ SND_SOC_DPCM_TRIGGER_POST}, -+ .dynamic = 0, -+ .playback_only = 1, -+ SND_SOC_DAILINK_REG(playback), -+ }, -+ { -+ .name = "wm8960-capture", -+ .stream_name = "wm8960-capture", -+ .trigger = {SND_SOC_DPCM_TRIGGER_POST, -+ SND_SOC_DPCM_TRIGGER_POST}, -+ .dynamic = 0, -+ .capture_only = 1, -+ SND_SOC_DAILINK_REG(capture), -+ }, -+ /* BE */ -+ { -+ .name = "wm8960-codec", -+ .no_pcm = 1, -+ .dai_fmt = SND_SOC_DAIFMT_I2S | -+ SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBC_CFC | -+ SND_SOC_DAIFMT_GATED, -+ SND_SOC_DAILINK_REG(codec), -+ }, -+}; -+ -+static struct snd_soc_card an7581_wm8960_card = { -+ .name = "an7581-wm8960", -+ .owner = THIS_MODULE, -+ .dai_link = an7581_wm8960_dai_links, -+ .num_links = ARRAY_SIZE(an7581_wm8960_dai_links), -+ .controls = an7581_wm8960_controls, -+ .num_controls = ARRAY_SIZE(an7581_wm8960_controls), -+ .dapm_widgets = an7581_wm8960_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(an7581_wm8960_widgets), -+}; -+ -+static int an7581_wm8960_machine_probe(struct platform_device *pdev) -+{ -+ struct device_node *platform_dai_node, *codec_dai_node; -+ struct snd_soc_card *card = &an7581_wm8960_card; -+ struct device_node *platform, *codec; -+ struct snd_soc_dai_link *dai_link; -+ int ret, i; -+ -+ card->dev = &pdev->dev; -+ -+ platform = of_get_child_by_name(pdev->dev.of_node, "platform"); -+ -+ if (platform) { -+ platform_dai_node = of_parse_phandle(platform, "sound-dai", 0); -+ of_node_put(platform); -+ -+ if (!platform_dai_node) { -+ dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n"); -+ return -EINVAL; -+ } -+ } else { -+ dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); -+ return -EINVAL; -+ } -+ -+ for_each_card_prelinks(card, i, dai_link) { -+ if (dai_link->platforms->name) -+ continue; -+ dai_link->platforms->of_node = platform_dai_node; -+ } -+ -+ codec = of_get_child_by_name(pdev->dev.of_node, "codec"); -+ -+ if (codec) { -+ codec_dai_node = of_parse_phandle(codec, "sound-dai", 0); -+ of_node_put(codec); -+ -+ if (!codec_dai_node) { -+ of_node_put(platform_dai_node); -+ dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n"); -+ return -EINVAL; -+ } -+ } else { -+ of_node_put(platform_dai_node); -+ dev_err(&pdev->dev, "Property 'codec' missing or invalid\n"); -+ return -EINVAL; -+ } -+ -+ for_each_card_prelinks(card, i, dai_link) { -+ if (dai_link->codecs->name) -+ continue; -+ dai_link->codecs->of_node = codec_dai_node; -+ } -+ -+ ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to parse audio-routing: %d\n", ret); -+ goto err_of_node_put; -+ } -+ -+ ret = devm_snd_soc_register_card(&pdev->dev, card); -+ if (ret) { -+ dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__); -+ goto err_of_node_put; -+ } -+ -+ return 0; -+ -+err_of_node_put: -+ of_node_put(platform_dai_node); -+ of_node_put(codec_dai_node); -+ return ret; -+} -+ -+static const struct of_device_id an7581_wm8960_machine_dt_match[] = { -+ { .compatible = "airoha,an7581-wm8960-sound" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, an7581_wm8960_machine_dt_match); -+ -+static struct platform_driver an7581_wm8960_driver = { -+ .driver = { -+ .name = "an7581-wm8960", -+ .of_match_table = an7581_wm8960_machine_dt_match, -+ }, -+ .probe = an7581_wm8960_machine_probe, -+}; -+module_platform_driver(an7581_wm8960_driver); -+ -+MODULE_DESCRIPTION("Airoha SoC I2S platform driver for ALSA AN7581"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/201-crypto-Add-Mediatek-EIP-93-crypto-engine-support.patch b/target/linux/airoha/patches-6.12/201-crypto-Add-Mediatek-EIP-93-crypto-engine-support.patch deleted file mode 100644 index 17923afd6ea..00000000000 --- a/target/linux/airoha/patches-6.12/201-crypto-Add-Mediatek-EIP-93-crypto-engine-support.patch +++ /dev/null @@ -1,4206 +0,0 @@ -From 45260ebcfb17a47bbad37055024dad50f2fcc5d0 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Oct 2021 17:13:29 +0800 -Subject: [RFC PATCH v2 3/3] crypto: Add Mediatek EIP-93 crypto engine support - -Add support for the Mediatek EIP-93 crypto engine used on MT7621 and new -Airoha SoC. - -EIP-93 IP supports AES/DES/3DES ciphers in ECB/CBC and CTR modes as well as -authenc(HMAC(x), cipher(y)) using HMAC MD5, SHA1, SHA224 and SHA256. - -EIP-93 provide regs to signal support for specific chipers and the -driver dynamically register only the supported one by the chip. - -Signed-off-by: Richard van Schagen -Co-developed-by: Christian Marangi -Signed-off-by: Christian Marangi ---- -Changes v2: -- Rename all variables from mtk to eip93 -- Move to inside-secure directory -- Check DMA map errors -- Use guard API for spinlock -- Minor improvements to code - - drivers/crypto/Kconfig | 1 + - drivers/crypto/Makefile | 1 + - drivers/crypto/inside-secure/eip93/Kconfig | 20 + - drivers/crypto/inside-secure/eip93/Makefile | 5 + - .../crypto/inside-secure/eip93/eip93-aead.c | 702 ++++++++++++++ - .../crypto/inside-secure/eip93/eip93-aead.h | 38 + - .../crypto/inside-secure/eip93/eip93-aes.h | 16 + - .../crypto/inside-secure/eip93/eip93-cipher.c | 407 ++++++++ - .../crypto/inside-secure/eip93/eip93-cipher.h | 60 ++ - .../crypto/inside-secure/eip93/eip93-common.c | 824 ++++++++++++++++ - .../crypto/inside-secure/eip93/eip93-common.h | 25 + - .../crypto/inside-secure/eip93/eip93-des.h | 16 + - .../crypto/inside-secure/eip93/eip93-hash.c | 909 ++++++++++++++++++ - .../crypto/inside-secure/eip93/eip93-hash.h | 72 ++ - .../crypto/inside-secure/eip93/eip93-main.c | 502 ++++++++++ - .../crypto/inside-secure/eip93/eip93-main.h | 155 +++ - .../crypto/inside-secure/eip93/eip93-regs.h | 335 +++++++ - 17 files changed, 4088 insertions(+) - create mode 100644 drivers/crypto/inside-secure/eip93/Kconfig - create mode 100644 drivers/crypto/inside-secure/eip93/Makefile - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-aead.c - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-aead.h - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-aes.h - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-cipher.c - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-cipher.h - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-common.c - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-common.h - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-des.h - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-hash.c - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-hash.h - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-main.c - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-main.h - create mode 100644 drivers/crypto/inside-secure/eip93/eip93-regs.h - ---- a/drivers/crypto/Kconfig -+++ b/drivers/crypto/Kconfig -@@ -851,5 +851,6 @@ config CRYPTO_DEV_SA2UL - - source "drivers/crypto/aspeed/Kconfig" - source "drivers/crypto/starfive/Kconfig" -+source "drivers/crypto/inside-secure/eip93/Kconfig" - - endif # CRYPTO_HW ---- a/drivers/crypto/Makefile -+++ b/drivers/crypto/Makefile -@@ -52,3 +52,4 @@ obj-y += hisilicon/ - obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ - obj-y += intel/ - obj-y += starfive/ -+obj-y += inside-secure/eip93/ ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/Kconfig -@@ -0,0 +1,20 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config CRYPTO_DEV_EIP93 -+ tristate "Support for EIP93 crypto HW accelerators" -+ depends on SOC_MT7621 || ARCH_AIROHA ||COMPILE_TEST -+ select CRYPTO_LIB_AES -+ select CRYPTO_LIB_DES -+ select CRYPTO_SKCIPHER -+ select CRYPTO_AEAD -+ select CRYPTO_AUTHENC -+ select CRYPTO_MD5 -+ select CRYPTO_SHA1 -+ select CRYPTO_SHA256 -+ help -+ EIP93 have various crypto HW accelerators. Select this if -+ you want to use the EIP93 modules for any of the crypto algorithms. -+ -+ If the IP supports it, this provide offload for AES - ECB, CBC and -+ CTR crypto. Also provide DES and 3DES ECB and CBC. -+ -+ Also provide AEAD authenc(hmac(x), cipher(y)) for supported algo. ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/Makefile -@@ -0,0 +1,5 @@ -+obj-$(CONFIG_CRYPTO_DEV_EIP93) += crypto-hw-eip93.o -+ -+crypto-hw-eip93-y += eip93-main.o eip93-common.o -+crypto-hw-eip93-y += eip93-cipher.o eip93-aead.o -+crypto-hw-eip93-y += eip93-hash.o ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-aead.c -@@ -0,0 +1,702 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include "eip93-aead.h" -+#include "eip93-cipher.h" -+#include "eip93-common.h" -+#include "eip93-regs.h" -+ -+void eip93_aead_handle_result(struct crypto_async_request *async, int err) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm); -+ struct eip93_device *mtk = ctx->mtk; -+ struct aead_request *req = aead_request_cast(async); -+ struct eip93_cipher_reqctx *rctx = aead_request_ctx(req); -+ -+ eip93_unmap_dma(mtk, rctx, req->src, req->dst); -+ eip93_handle_result(mtk, rctx, req->iv); -+ -+ aead_request_complete(req, err); -+} -+ -+static int eip93_aead_send_req(struct crypto_async_request *async) -+{ -+ struct aead_request *req = aead_request_cast(async); -+ struct eip93_cipher_reqctx *rctx = aead_request_ctx(req); -+ int err; -+ -+ err = check_valid_request(rctx); -+ if (err) { -+ aead_request_complete(req, err); -+ return err; -+ } -+ -+ return eip93_send_req(async, req->iv, rctx); -+} -+ -+/* Crypto aead API functions */ -+static int eip93_aead_cra_init(struct crypto_tfm *tfm) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg, -+ struct eip93_alg_template, alg.aead.base); -+ -+ crypto_aead_set_reqsize(__crypto_aead_cast(tfm), -+ sizeof(struct eip93_cipher_reqctx)); -+ -+ ctx->mtk = tmpl->mtk; -+ ctx->flags = tmpl->flags; -+ ctx->type = tmpl->type; -+ ctx->set_assoc = true; -+ -+ ctx->sa_record = kzalloc(sizeof(*ctx->sa_record), GFP_KERNEL); -+ if (!ctx->sa_record) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static void eip93_aead_cra_exit(struct crypto_tfm *tfm) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ -+ dma_unmap_single(ctx->mtk->dev, ctx->sa_record_base, -+ sizeof(*ctx->sa_record), DMA_TO_DEVICE); -+ kfree(ctx->sa_record); -+} -+ -+static int eip93_aead_setkey(struct crypto_aead *ctfm, const u8 *key, -+ unsigned int len) -+{ -+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct crypto_authenc_keys keys; -+ struct crypto_aes_ctx aes; -+ struct sa_record *sa_record = ctx->sa_record; -+ u32 nonce = 0; -+ int ret; -+ -+ if (crypto_authenc_extractkeys(&keys, key, len)) -+ return -EINVAL; -+ -+ if (IS_RFC3686(ctx->flags)) { -+ if (keys.enckeylen < CTR_RFC3686_NONCE_SIZE) -+ return -EINVAL; -+ -+ keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; -+ memcpy(&nonce, keys.enckey + keys.enckeylen, -+ CTR_RFC3686_NONCE_SIZE); -+ } -+ -+ switch ((ctx->flags & EIP93_ALG_MASK)) { -+ case EIP93_ALG_DES: -+ ret = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); -+ break; -+ case EIP93_ALG_3DES: -+ if (keys.enckeylen != DES3_EDE_KEY_SIZE) -+ return -EINVAL; -+ -+ ret = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); -+ break; -+ case EIP93_ALG_AES: -+ ret = aes_expandkey(&aes, keys.enckey, keys.enckeylen); -+ } -+ if (ret) -+ return ret; -+ -+ ctx->blksize = crypto_aead_blocksize(ctfm); -+ /* Encryption key */ -+ eip93_set_sa_record(sa_record, keys.enckeylen, ctx->flags); -+ sa_record->sa_cmd0_word &= ~EIP93_SA_CMD_OPCODE; -+ sa_record->sa_cmd0_word |= FIELD_PREP(EIP93_SA_CMD_OPCODE, -+ EIP93_SA_CMD_OPCODE_BASIC_OUT_ENC_HASH); -+ sa_record->sa_cmd0_word &= ~EIP93_SA_CMD_DIGEST_LENGTH; -+ sa_record->sa_cmd0_word |= FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, -+ ctx->authsize / sizeof(u32)); -+ -+ memcpy(sa_record->sa_key, keys.enckey, keys.enckeylen); -+ ctx->sa_nonce = nonce; -+ sa_record->sa_nonce = nonce; -+ -+ /* authentication key */ -+ ret = eip93_authenc_setkey(ctfm, sa_record, keys.authkey, -+ keys.authkeylen); -+ -+ ctx->set_assoc = true; -+ -+ return ret; -+} -+ -+static int eip93_aead_setauthsize(struct crypto_aead *ctfm, -+ unsigned int authsize) -+{ -+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ -+ ctx->authsize = authsize; -+ ctx->sa_record->sa_cmd0_word &= ~EIP93_SA_CMD_DIGEST_LENGTH; -+ ctx->sa_record->sa_cmd0_word |= FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, -+ ctx->authsize / sizeof(u32)); -+ -+ return 0; -+} -+ -+static void eip93_aead_setassoc(struct eip93_crypto_ctx *ctx, -+ struct aead_request *req) -+{ -+ struct sa_record *sa_record = ctx->sa_record; -+ -+ sa_record->sa_cmd1_word &= ~EIP93_SA_CMD_HASH_CRYPT_OFFSET; -+ sa_record->sa_cmd1_word |= FIELD_PREP(EIP93_SA_CMD_HASH_CRYPT_OFFSET, -+ req->assoclen / sizeof(u32)); -+ -+ ctx->assoclen = req->assoclen; -+} -+ -+static int eip93_aead_crypt(struct aead_request *req) -+{ -+ struct eip93_cipher_reqctx *rctx = aead_request_ctx(req); -+ struct crypto_async_request *async = &req->base; -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); -+ struct crypto_aead *aead = crypto_aead_reqtfm(req); -+ int ret; -+ -+ ctx->sa_record_base = dma_map_single(ctx->mtk->dev, ctx->sa_record, -+ sizeof(*ctx->sa_record), DMA_TO_DEVICE); -+ ret = dma_mapping_error(ctx->mtk->dev, ctx->sa_record_base); -+ if (ret) -+ return ret; -+ -+ rctx->textsize = req->cryptlen; -+ rctx->blksize = ctx->blksize; -+ rctx->assoclen = req->assoclen; -+ rctx->authsize = ctx->authsize; -+ rctx->sg_src = req->src; -+ rctx->sg_dst = req->dst; -+ rctx->ivsize = crypto_aead_ivsize(aead); -+ rctx->desc_flags = EIP93_DESC_AEAD; -+ rctx->sa_record_base = ctx->sa_record_base; -+ -+ if (IS_DECRYPT(rctx->flags)) -+ rctx->textsize -= rctx->authsize; -+ -+ return eip93_aead_send_req(async); -+} -+ -+static int eip93_aead_encrypt(struct aead_request *req) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); -+ struct eip93_cipher_reqctx *rctx = aead_request_ctx(req); -+ -+ rctx->flags = ctx->flags; -+ rctx->flags |= EIP93_ENCRYPT; -+ if (ctx->set_assoc) { -+ eip93_aead_setassoc(ctx, req); -+ ctx->set_assoc = false; -+ } -+ -+ if (req->assoclen != ctx->assoclen) { -+ dev_err(ctx->mtk->dev, "Request AAD length error\n"); -+ return -EINVAL; -+ } -+ -+ return eip93_aead_crypt(req); -+} -+ -+static int eip93_aead_decrypt(struct aead_request *req) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); -+ struct eip93_cipher_reqctx *rctx = aead_request_ctx(req); -+ -+ ctx->sa_record->sa_cmd0_word |= EIP93_SA_CMD_DIRECTION_IN; -+ ctx->sa_record->sa_cmd1_word &= ~(EIP93_SA_CMD_COPY_PAD | -+ EIP93_SA_CMD_COPY_DIGEST); -+ -+ rctx->flags = ctx->flags; -+ rctx->flags |= EIP93_DECRYPT; -+ if (ctx->set_assoc) { -+ eip93_aead_setassoc(ctx, req); -+ ctx->set_assoc = false; -+ } -+ -+ if (req->assoclen != ctx->assoclen) { -+ dev_err(ctx->mtk->dev, "Request AAD length error\n"); -+ return -EINVAL; -+ } -+ -+ return eip93_aead_crypt(req); -+} -+ -+/* Available authenc algorithms in this module */ -+struct eip93_alg_template eip93_alg_authenc_hmac_md5_cbc_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_MD5 | EIP93_MODE_CBC | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = AES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = MD5_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(md5),cbc(aes))", -+ .cra_driver_name = -+ "authenc(hmac(md5-eip93), cbc(aes-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = AES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha1_cbc_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA1 | EIP93_MODE_CBC | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = AES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA1_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha1),cbc(aes))", -+ .cra_driver_name = -+ "authenc(hmac(sha1-eip93),cbc(aes-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = AES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha224_cbc_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA224 | EIP93_MODE_CBC | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = AES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA224_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha224),cbc(aes))", -+ .cra_driver_name = -+ "authenc(hmac(sha224-eip93),cbc(aes-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = AES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha256_cbc_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA256 | EIP93_MODE_CBC | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = AES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA256_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha256),cbc(aes))", -+ .cra_driver_name = -+ "authenc(hmac(sha256-eip93),cbc(aes-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = AES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_md5_rfc3686_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_MD5 | -+ EIP93_MODE_CTR | EIP93_MODE_RFC3686 | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = CTR_RFC3686_IV_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = MD5_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(md5),rfc3686(ctr(aes)))", -+ .cra_driver_name = -+ "authenc(hmac(md5-eip93),rfc3686(ctr(aes-eip93)))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = 1, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha1_rfc3686_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA1 | -+ EIP93_MODE_CTR | EIP93_MODE_RFC3686 | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = CTR_RFC3686_IV_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA1_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", -+ .cra_driver_name = -+ "authenc(hmac(sha1-eip93),rfc3686(ctr(aes-eip93)))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = 1, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha224_rfc3686_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA224 | -+ EIP93_MODE_CTR | EIP93_MODE_RFC3686 | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = CTR_RFC3686_IV_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA224_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", -+ .cra_driver_name = -+ "authenc(hmac(sha224-eip93),rfc3686(ctr(aes-eip93)))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = 1, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha256_rfc3686_aes = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA256 | -+ EIP93_MODE_CTR | EIP93_MODE_RFC3686 | EIP93_ALG_AES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = CTR_RFC3686_IV_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA256_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", -+ .cra_driver_name = -+ "authenc(hmac(sha256-eip93),rfc3686(ctr(aes-eip93)))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = 1, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_md5_cbc_des = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_MD5 | EIP93_MODE_CBC | EIP93_ALG_DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = MD5_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(md5),cbc(des))", -+ .cra_driver_name = -+ "authenc(hmac(md5-eip93),cbc(des-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha1_cbc_des = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA1 | EIP93_MODE_CBC | EIP93_ALG_DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA1_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha1),cbc(des))", -+ .cra_driver_name = -+ "authenc(hmac(sha1-eip93),cbc(des-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha224_cbc_des = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA224 | EIP93_MODE_CBC | EIP93_ALG_DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA224_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha224),cbc(des))", -+ .cra_driver_name = -+ "authenc(hmac(sha224-eip93),cbc(des-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha256_cbc_des = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA256 | EIP93_MODE_CBC | EIP93_ALG_DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA256_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha256),cbc(des))", -+ .cra_driver_name = -+ "authenc(hmac(sha256-eip93),cbc(des-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_md5_cbc_des3_ede = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_MD5 | EIP93_MODE_CBC | EIP93_ALG_3DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = MD5_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(md5),cbc(des3_ede))", -+ .cra_driver_name = -+ "authenc(hmac(md5-eip93),cbc(des3_ede-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0x0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha1_cbc_des3_ede = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA1 | EIP93_MODE_CBC | EIP93_ALG_3DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA1_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", -+ .cra_driver_name = -+ "authenc(hmac(sha1-eip93),cbc(des3_ede-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0x0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha224_cbc_des3_ede = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA224 | EIP93_MODE_CBC | EIP93_ALG_3DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA224_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", -+ .cra_driver_name = -+ "authenc(hmac(sha224-eip93),cbc(des3_ede-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0x0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_authenc_hmac_sha256_cbc_des3_ede = { -+ .type = EIP93_ALG_TYPE_AEAD, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA256 | EIP93_MODE_CBC | EIP93_ALG_3DES, -+ .alg.aead = { -+ .setkey = eip93_aead_setkey, -+ .encrypt = eip93_aead_encrypt, -+ .decrypt = eip93_aead_decrypt, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .setauthsize = eip93_aead_setauthsize, -+ .maxauthsize = SHA256_DIGEST_SIZE, -+ .base = { -+ .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", -+ .cra_driver_name = -+ "authenc(hmac(sha256-eip93),cbc(des3_ede-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0x0, -+ .cra_init = eip93_aead_cra_init, -+ .cra_exit = eip93_aead_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-aead.h -@@ -0,0 +1,38 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -+ * Christian Marangi -+ * Christian Marangi -+#include -+#include -+#include -+ -+#include "eip93-cipher.h" -+#include "eip93-common.h" -+#include "eip93-regs.h" -+ -+void eip93_skcipher_handle_result(struct crypto_async_request *async, int err) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm); -+ struct eip93_device *mtk = ctx->mtk; -+ struct skcipher_request *req = skcipher_request_cast(async); -+ struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req); -+ -+ eip93_unmap_dma(mtk, rctx, req->src, req->dst); -+ eip93_handle_result(mtk, rctx, req->iv); -+ -+ skcipher_request_complete(req, err); -+} -+ -+static int eip93_skcipher_send_req(struct crypto_async_request *async) -+{ -+ struct skcipher_request *req = skcipher_request_cast(async); -+ struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req); -+ int err; -+ -+ err = check_valid_request(rctx); -+ -+ if (err) { -+ skcipher_request_complete(req, err); -+ return err; -+ } -+ -+ return eip93_send_req(async, req->iv, rctx); -+} -+ -+/* Crypto skcipher API functions */ -+static int eip93_skcipher_cra_init(struct crypto_tfm *tfm) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg, -+ struct eip93_alg_template, alg.skcipher.base); -+ -+ crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm), -+ sizeof(struct eip93_cipher_reqctx)); -+ -+ memset(ctx, 0, sizeof(*ctx)); -+ -+ ctx->mtk = tmpl->mtk; -+ ctx->type = tmpl->type; -+ -+ ctx->sa_record = kzalloc(sizeof(*ctx->sa_record), GFP_KERNEL); -+ if (!ctx->sa_record) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static void eip93_skcipher_cra_exit(struct crypto_tfm *tfm) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ -+ dma_unmap_single(ctx->mtk->dev, ctx->sa_record_base, -+ sizeof(*ctx->sa_record), DMA_TO_DEVICE); -+ kfree(ctx->sa_record); -+} -+ -+static int eip93_skcipher_setkey(struct crypto_skcipher *ctfm, const u8 *key, -+ unsigned int len) -+{ -+ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg, -+ struct eip93_alg_template, -+ alg.skcipher.base); -+ struct sa_record *sa_record = ctx->sa_record; -+ unsigned int keylen = len; -+ u32 flags = tmpl->flags; -+ u32 nonce = 0; -+ int ret; -+ -+ if (!key || !keylen) -+ return -EINVAL; -+ -+ if (IS_RFC3686(flags)) { -+ if (len < CTR_RFC3686_NONCE_SIZE) -+ return -EINVAL; -+ -+ keylen = len - CTR_RFC3686_NONCE_SIZE; -+ memcpy(&nonce, key + keylen, CTR_RFC3686_NONCE_SIZE); -+ } -+ -+ if (flags & EIP93_ALG_DES) { -+ ctx->blksize = DES_BLOCK_SIZE; -+ ret = verify_skcipher_des_key(ctfm, key); -+ } -+ if (flags & EIP93_ALG_3DES) { -+ ctx->blksize = DES3_EDE_BLOCK_SIZE; -+ ret = verify_skcipher_des3_key(ctfm, key); -+ } -+ -+ if (flags & EIP93_ALG_AES) { -+ struct crypto_aes_ctx aes; -+ -+ ctx->blksize = AES_BLOCK_SIZE; -+ ret = aes_expandkey(&aes, key, keylen); -+ } -+ if (ret) -+ return ret; -+ -+ eip93_set_sa_record(sa_record, keylen, flags); -+ -+ memcpy(sa_record->sa_key, key, keylen); -+ ctx->sa_nonce = nonce; -+ sa_record->sa_nonce = nonce; -+ -+ return 0; -+} -+ -+static int eip93_skcipher_crypt(struct skcipher_request *req) -+{ -+ struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req); -+ struct crypto_async_request *async = &req->base; -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); -+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); -+ int ret; -+ -+ if (!req->cryptlen) -+ return 0; -+ -+ /* -+ * ECB and CBC algorithms require message lengths to be -+ * multiples of block size. -+ */ -+ if (IS_ECB(rctx->flags) || IS_CBC(rctx->flags)) -+ if (!IS_ALIGNED(req->cryptlen, -+ crypto_skcipher_blocksize(skcipher))) -+ return -EINVAL; -+ -+ ctx->sa_record_base = dma_map_single(ctx->mtk->dev, ctx->sa_record, -+ sizeof(*ctx->sa_record), DMA_TO_DEVICE); -+ ret = dma_mapping_error(ctx->mtk->dev, ctx->sa_record_base); -+ if (ret) -+ return ret; -+ -+ rctx->assoclen = 0; -+ rctx->textsize = req->cryptlen; -+ rctx->authsize = 0; -+ rctx->sg_src = req->src; -+ rctx->sg_dst = req->dst; -+ rctx->ivsize = crypto_skcipher_ivsize(skcipher); -+ rctx->blksize = ctx->blksize; -+ rctx->desc_flags = EIP93_DESC_SKCIPHER; -+ rctx->sa_record_base = ctx->sa_record_base; -+ -+ return eip93_skcipher_send_req(async); -+} -+ -+static int eip93_skcipher_encrypt(struct skcipher_request *req) -+{ -+ struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req); -+ struct eip93_alg_template *tmpl = container_of(req->base.tfm->__crt_alg, -+ struct eip93_alg_template, alg.skcipher.base); -+ -+ rctx->flags = tmpl->flags; -+ rctx->flags |= EIP93_ENCRYPT; -+ -+ return eip93_skcipher_crypt(req); -+} -+ -+static int eip93_skcipher_decrypt(struct skcipher_request *req) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); -+ struct eip93_cipher_reqctx *rctx = skcipher_request_ctx(req); -+ struct eip93_alg_template *tmpl = container_of(req->base.tfm->__crt_alg, -+ struct eip93_alg_template, alg.skcipher.base); -+ -+ ctx->sa_record->sa_cmd0_word |= EIP93_SA_CMD_DIRECTION_IN; -+ -+ rctx->flags = tmpl->flags; -+ rctx->flags |= EIP93_DECRYPT; -+ -+ return eip93_skcipher_crypt(req); -+} -+ -+/* Available algorithms in this module */ -+struct eip93_alg_template eip93_alg_ecb_aes = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_ECB | EIP93_ALG_AES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ .ivsize = 0, -+ .base = { -+ .cra_name = "ecb(aes)", -+ .cra_driver_name = "ecb(aes-eip93)", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_NEED_FALLBACK | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = AES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0xf, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_cbc_aes = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_CBC | EIP93_ALG_AES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ .ivsize = AES_BLOCK_SIZE, -+ .base = { -+ .cra_name = "cbc(aes)", -+ .cra_driver_name = "cbc(aes-eip93)", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_NEED_FALLBACK | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = AES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0xf, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_ctr_aes = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_CTR | EIP93_ALG_AES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ .ivsize = AES_BLOCK_SIZE, -+ .base = { -+ .cra_name = "ctr(aes)", -+ .cra_driver_name = "ctr(aes-eip93)", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_NEED_FALLBACK | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = 1, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0xf, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_rfc3686_aes = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_CTR | EIP93_MODE_RFC3686 | EIP93_ALG_AES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, -+ .ivsize = CTR_RFC3686_IV_SIZE, -+ .base = { -+ .cra_name = "rfc3686(ctr(aes))", -+ .cra_driver_name = "rfc3686(ctr(aes-eip93))", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_NEED_FALLBACK | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = 1, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0xf, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_ecb_des = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_ECB | EIP93_ALG_DES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = DES_KEY_SIZE, -+ .max_keysize = DES_KEY_SIZE, -+ .ivsize = 0, -+ .base = { -+ .cra_name = "ecb(des)", -+ .cra_driver_name = "ebc(des-eip93)", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_cbc_des = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_CBC | EIP93_ALG_DES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = DES_KEY_SIZE, -+ .max_keysize = DES_KEY_SIZE, -+ .ivsize = DES_BLOCK_SIZE, -+ .base = { -+ .cra_name = "cbc(des)", -+ .cra_driver_name = "cbc(des-eip93)", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_ecb_des3_ede = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_ECB | EIP93_ALG_3DES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = DES3_EDE_KEY_SIZE, -+ .max_keysize = DES3_EDE_KEY_SIZE, -+ .ivsize = 0, -+ .base = { -+ .cra_name = "ecb(des3_ede)", -+ .cra_driver_name = "ecb(des3_ede-eip93)", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_cbc_des3_ede = { -+ .type = EIP93_ALG_TYPE_SKCIPHER, -+ .flags = EIP93_MODE_CBC | EIP93_ALG_3DES, -+ .alg.skcipher = { -+ .setkey = eip93_skcipher_setkey, -+ .encrypt = eip93_skcipher_encrypt, -+ .decrypt = eip93_skcipher_decrypt, -+ .min_keysize = DES3_EDE_KEY_SIZE, -+ .max_keysize = DES3_EDE_KEY_SIZE, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .base = { -+ .cra_name = "cbc(des3_ede)", -+ .cra_driver_name = "cbc(des3_ede-eip93)", -+ .cra_priority = EIP93_CRA_PRIORITY, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY, -+ .cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_crypto_ctx), -+ .cra_alignmask = 0, -+ .cra_init = eip93_skcipher_cra_init, -+ .cra_exit = eip93_skcipher_cra_exit, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+}; ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-cipher.h -@@ -0,0 +1,60 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -+ * Christian Marangi -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "eip93-cipher.h" -+#include "eip93-hash.h" -+#include "eip93-common.h" -+#include "eip93-main.h" -+#include "eip93-regs.h" -+ -+int eip93_parse_ctrl_stat_err(struct eip93_device *mtk, int err) -+{ -+ u32 ext_err; -+ -+ if (!err) -+ return 0; -+ -+ switch (err & ~EIP93_PE_CTRL_PE_EXT_ERR_CODE) { -+ case EIP93_PE_CTRL_PE_AUTH_ERR: -+ case EIP93_PE_CTRL_PE_PAD_ERR: -+ return -EBADMSG; -+ /* let software handle anti-replay errors */ -+ case EIP93_PE_CTRL_PE_SEQNUM_ERR: -+ return 0; -+ case EIP93_PE_CTRL_PE_EXT_ERR: -+ break; -+ default: -+ dev_err(mtk->dev, "Unhandled error 0x%08x\n", err); -+ return -EINVAL; -+ } -+ -+ /* Parse additional ext errors */ -+ ext_err = FIELD_GET(EIP93_PE_CTRL_PE_EXT_ERR_CODE, err); -+ switch (ext_err) { -+ case EIP93_PE_CTRL_PE_EXT_ERR_BUS: -+ case EIP93_PE_CTRL_PE_EXT_ERR_PROCESSING: -+ return -EIO; -+ case EIP93_PE_CTRL_PE_EXT_ERR_DESC_OWNER: -+ return -EACCES; -+ case EIP93_PE_CTRL_PE_EXT_ERR_INVALID_CRYPTO_OP: -+ case EIP93_PE_CTRL_PE_EXT_ERR_INVALID_CRYPTO_ALGO: -+ case EIP93_PE_CTRL_PE_EXT_ERR_SPI: -+ return -EINVAL; -+ case EIP93_PE_CTRL_PE_EXT_ERR_ZERO_LENGTH: -+ case EIP93_PE_CTRL_PE_EXT_ERR_INVALID_PK_LENGTH: -+ case EIP93_PE_CTRL_PE_EXT_ERR_BLOCK_SIZE_ERR: -+ return -EBADMSG; -+ default: -+ dev_err(mtk->dev, "Unhandled ext error 0x%08x\n", ext_err); -+ return -EINVAL; -+ } -+} -+ -+static void *eip93_ring_next_wptr(struct eip93_device *mtk, -+ struct eip93_desc_ring *ring) -+{ -+ void *ptr = ring->write; -+ -+ if ((ring->write == ring->read - ring->offset) || -+ (ring->read == ring->base && ring->write == ring->base_end)) -+ return ERR_PTR(-ENOMEM); -+ -+ if (ring->write == ring->base_end) -+ ring->write = ring->base; -+ else -+ ring->write += ring->offset; -+ -+ return ptr; -+} -+ -+static void *eip93_ring_next_rptr(struct eip93_device *mtk, -+ struct eip93_desc_ring *ring) -+{ -+ void *ptr = ring->read; -+ -+ if (ring->write == ring->read) -+ return ERR_PTR(-ENOENT); -+ -+ if (ring->read == ring->base_end) -+ ring->read = ring->base; -+ else -+ ring->read += ring->offset; -+ -+ return ptr; -+} -+ -+int eip93_put_descriptor(struct eip93_device *mtk, -+ struct eip93_descriptor *desc) -+{ -+ struct eip93_descriptor *cdesc; -+ struct eip93_descriptor *rdesc; -+ -+ guard(spinlock_irqsave)(&mtk->ring->write_lock); -+ -+ rdesc = eip93_ring_next_wptr(mtk, &mtk->ring->rdr); -+ -+ if (IS_ERR(rdesc)) -+ return -ENOENT; -+ -+ cdesc = eip93_ring_next_wptr(mtk, &mtk->ring->cdr); -+ if (IS_ERR(cdesc)) -+ return -ENOENT; -+ -+ memset(rdesc, 0, sizeof(struct eip93_descriptor)); -+ -+ memcpy(cdesc, desc, sizeof(struct eip93_descriptor)); -+ -+ atomic_dec(&mtk->ring->free); -+ -+ return 0; -+} -+ -+void *eip93_get_descriptor(struct eip93_device *mtk) -+{ -+ struct eip93_descriptor *cdesc; -+ void *ptr; -+ -+ guard(spinlock_irqsave)(&mtk->ring->read_lock); -+ -+ cdesc = eip93_ring_next_rptr(mtk, &mtk->ring->cdr); -+ if (IS_ERR(cdesc)) -+ return ERR_PTR(-ENOENT); -+ -+ memset(cdesc, 0, sizeof(struct eip93_descriptor)); -+ -+ ptr = eip93_ring_next_rptr(mtk, &mtk->ring->rdr); -+ if (IS_ERR(ptr)) -+ return ERR_PTR(-ENOENT); -+ -+ atomic_inc(&mtk->ring->free); -+ -+ return ptr; -+} -+ -+static void eip93_free_sg_copy(const int len, struct scatterlist **sg) -+{ -+ if (!*sg || !len) -+ return; -+ -+ free_pages((unsigned long)sg_virt(*sg), get_order(len)); -+ kfree(*sg); -+ *sg = NULL; -+} -+ -+static int eip93_make_sg_copy(struct scatterlist *src, struct scatterlist **dst, -+ const u32 len, const bool copy) -+{ -+ void *pages; -+ -+ *dst = kmalloc(sizeof(**dst), GFP_KERNEL); -+ if (!*dst) -+ return -ENOMEM; -+ -+ pages = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, -+ get_order(len)); -+ if (!pages) { -+ kfree(*dst); -+ *dst = NULL; -+ return -ENOMEM; -+ } -+ -+ sg_init_table(*dst, 1); -+ sg_set_buf(*dst, pages, len); -+ -+ /* copy only as requested */ -+ if (copy) -+ sg_copy_to_buffer(src, sg_nents(src), pages, len); -+ -+ return 0; -+} -+ -+static bool eip93_is_sg_aligned(struct scatterlist *sg, u32 len, -+ const int blksize) -+{ -+ int nents; -+ -+ for (nents = 0; sg; sg = sg_next(sg), ++nents) { -+ if (!IS_ALIGNED(sg->offset, 4)) -+ return false; -+ -+ if (len <= sg->length) { -+ if (!IS_ALIGNED(len, blksize)) -+ return false; -+ -+ return true; -+ } -+ -+ if (!IS_ALIGNED(sg->length, blksize)) -+ return false; -+ -+ len -= sg->length; -+ } -+ return false; -+} -+ -+int check_valid_request(struct eip93_cipher_reqctx *rctx) -+{ -+ struct scatterlist *src = rctx->sg_src; -+ struct scatterlist *dst = rctx->sg_dst; -+ u32 src_nents, dst_nents; -+ u32 textsize = rctx->textsize; -+ u32 authsize = rctx->authsize; -+ u32 blksize = rctx->blksize; -+ u32 totlen_src = rctx->assoclen + rctx->textsize; -+ u32 totlen_dst = rctx->assoclen + rctx->textsize; -+ u32 copy_len; -+ bool src_align, dst_align; -+ int err = -EINVAL; -+ -+ if (!IS_CTR(rctx->flags)) { -+ if (!IS_ALIGNED(textsize, blksize)) -+ return err; -+ } -+ -+ if (authsize) { -+ if (IS_ENCRYPT(rctx->flags)) -+ totlen_dst += authsize; -+ else -+ totlen_src += authsize; -+ } -+ -+ src_nents = sg_nents_for_len(src, totlen_src); -+ dst_nents = sg_nents_for_len(dst, totlen_dst); -+ -+ if (src == dst) { -+ src_nents = max(src_nents, dst_nents); -+ dst_nents = src_nents; -+ if (unlikely((totlen_src || totlen_dst) && src_nents <= 0)) -+ return err; -+ -+ } else { -+ if (unlikely(totlen_src && src_nents <= 0)) -+ return err; -+ -+ if (unlikely(totlen_dst && dst_nents <= 0)) -+ return err; -+ } -+ -+ if (authsize) { -+ if (dst_nents == 1 && src_nents == 1) { -+ src_align = eip93_is_sg_aligned(src, totlen_src, blksize); -+ if (src == dst) -+ dst_align = src_align; -+ else -+ dst_align = eip93_is_sg_aligned(dst, totlen_dst, blksize); -+ } else { -+ src_align = false; -+ dst_align = false; -+ } -+ } else { -+ src_align = eip93_is_sg_aligned(src, totlen_src, blksize); -+ if (src == dst) -+ dst_align = src_align; -+ else -+ dst_align = eip93_is_sg_aligned(dst, totlen_dst, blksize); -+ } -+ -+ copy_len = max(totlen_src, totlen_dst); -+ if (!src_align) { -+ err = eip93_make_sg_copy(src, &rctx->sg_src, copy_len, true); -+ if (err) -+ return err; -+ } -+ -+ if (!dst_align) { -+ err = eip93_make_sg_copy(dst, &rctx->sg_dst, copy_len, false); -+ if (err) -+ return err; -+ } -+ -+ rctx->src_nents = sg_nents_for_len(rctx->sg_src, totlen_src); -+ rctx->dst_nents = sg_nents_for_len(rctx->sg_dst, totlen_dst); -+ -+ return 0; -+} -+ -+/* -+ * Set sa_record function: -+ * Even sa_record is set to "0", keep " = 0" for readability. -+ */ -+void eip93_set_sa_record(struct sa_record *sa_record, const unsigned int keylen, -+ const u32 flags) -+{ -+ /* Reset cmd word */ -+ sa_record->sa_cmd0_word = 0; -+ sa_record->sa_cmd1_word = 0; -+ -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_IV_FROM_STATE; -+ if (!IS_ECB(flags)) -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_SAVE_IV; -+ -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_OP_BASIC; -+ -+ switch ((flags & EIP93_ALG_MASK)) { -+ case EIP93_ALG_AES: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_CIPHER_AES; -+ sa_record->sa_cmd1_word |= FIELD_PREP(EIP93_SA_CMD_AES_KEY_LENGTH, -+ keylen >> 3); -+ break; -+ case EIP93_ALG_3DES: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_CIPHER_3DES; -+ break; -+ case EIP93_ALG_DES: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_CIPHER_DES; -+ break; -+ default: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_CIPHER_NULL; -+ } -+ -+ switch ((flags & EIP93_HASH_MASK)) { -+ case EIP93_HASH_SHA256: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_HASH_SHA256; -+ break; -+ case EIP93_HASH_SHA224: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_HASH_SHA224; -+ break; -+ case EIP93_HASH_SHA1: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_HASH_SHA1; -+ break; -+ case EIP93_HASH_MD5: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_HASH_MD5; -+ break; -+ default: -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_HASH_NULL; -+ } -+ -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_PAD_ZERO; -+ -+ switch ((flags & EIP93_MODE_MASK)) { -+ case EIP93_MODE_CBC: -+ sa_record->sa_cmd1_word |= EIP93_SA_CMD_CHIPER_MODE_CBC; -+ break; -+ case EIP93_MODE_CTR: -+ sa_record->sa_cmd1_word |= EIP93_SA_CMD_CHIPER_MODE_CTR; -+ break; -+ case EIP93_MODE_ECB: -+ sa_record->sa_cmd1_word |= EIP93_SA_CMD_CHIPER_MODE_ECB; -+ break; -+ } -+ -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_DIGEST_3WORD; -+ if (IS_HASH(flags)) { -+ sa_record->sa_cmd1_word |= EIP93_SA_CMD_COPY_PAD; -+ sa_record->sa_cmd1_word |= EIP93_SA_CMD_COPY_DIGEST; -+ } -+ -+ if (IS_HMAC(flags)) { -+ sa_record->sa_cmd1_word |= EIP93_SA_CMD_HMAC; -+ sa_record->sa_cmd1_word |= EIP93_SA_CMD_COPY_HEADER; -+ } -+ -+ sa_record->sa_spi = 0x0; -+ sa_record->sa_seqmum_mask[0] = 0xFFFFFFFF; -+ sa_record->sa_seqmum_mask[1] = 0x0; -+} -+ -+/* -+ * Poor mans Scatter/gather function: -+ * Create a Descriptor for every segment to avoid copying buffers. -+ * For performance better to wait for hardware to perform multiple DMA -+ */ -+static int eip93_scatter_combine(struct eip93_device *mtk, -+ struct eip93_cipher_reqctx *rctx, -+ u32 datalen, u32 split, int offsetin) -+{ -+ struct eip93_descriptor *cdesc = rctx->cdesc; -+ struct scatterlist *sgsrc = rctx->sg_src; -+ struct scatterlist *sgdst = rctx->sg_dst; -+ unsigned int remainin = sg_dma_len(sgsrc); -+ unsigned int remainout = sg_dma_len(sgdst); -+ dma_addr_t saddr = sg_dma_address(sgsrc); -+ dma_addr_t daddr = sg_dma_address(sgdst); -+ dma_addr_t state_addr; -+ u32 src_addr, dst_addr, len, n; -+ bool nextin = false; -+ bool nextout = false; -+ int offsetout = 0; -+ int ndesc_cdr = 0, err; -+ -+ if (IS_ECB(rctx->flags)) -+ rctx->sa_state_base = 0; -+ -+ if (split < datalen) { -+ state_addr = rctx->sa_state_ctr_base; -+ n = split; -+ } else { -+ state_addr = rctx->sa_state_base; -+ n = datalen; -+ } -+ -+ do { -+ if (nextin) { -+ sgsrc = sg_next(sgsrc); -+ remainin = sg_dma_len(sgsrc); -+ if (remainin == 0) -+ continue; -+ -+ saddr = sg_dma_address(sgsrc); -+ offsetin = 0; -+ nextin = false; -+ } -+ -+ if (nextout) { -+ sgdst = sg_next(sgdst); -+ remainout = sg_dma_len(sgdst); -+ if (remainout == 0) -+ continue; -+ -+ daddr = sg_dma_address(sgdst); -+ offsetout = 0; -+ nextout = false; -+ } -+ src_addr = saddr + offsetin; -+ dst_addr = daddr + offsetout; -+ -+ if (remainin == remainout) { -+ len = remainin; -+ if (len > n) { -+ len = n; -+ remainin -= n; -+ remainout -= n; -+ offsetin += n; -+ offsetout += n; -+ } else { -+ nextin = true; -+ nextout = true; -+ } -+ } else if (remainin < remainout) { -+ len = remainin; -+ if (len > n) { -+ len = n; -+ remainin -= n; -+ remainout -= n; -+ offsetin += n; -+ offsetout += n; -+ } else { -+ offsetout += len; -+ remainout -= len; -+ nextin = true; -+ } -+ } else { -+ len = remainout; -+ if (len > n) { -+ len = n; -+ remainin -= n; -+ remainout -= n; -+ offsetin += n; -+ offsetout += n; -+ } else { -+ offsetin += len; -+ remainin -= len; -+ nextout = true; -+ } -+ } -+ n -= len; -+ -+ cdesc->src_addr = src_addr; -+ cdesc->dst_addr = dst_addr; -+ cdesc->state_addr = state_addr; -+ cdesc->pe_length_word = FIELD_PREP(EIP93_PE_LENGTH_HOST_PE_READY, -+ EIP93_PE_LENGTH_HOST_READY); -+ cdesc->pe_length_word |= FIELD_PREP(EIP93_PE_LENGTH_LENGTH, len); -+ -+ if (n == 0) { -+ n = datalen - split; -+ split = datalen; -+ state_addr = rctx->sa_state_base; -+ } -+ -+ if (n == 0) -+ cdesc->user_id |= FIELD_PREP(EIP93_PE_USER_ID_DESC_FLAGS, -+ EIP93_DESC_LAST); -+ -+ /* -+ * Loop - Delay - No need to rollback -+ * Maybe refine by slowing down at EIP93_RING_BUSY -+ */ -+again: -+ err = eip93_put_descriptor(mtk, cdesc); -+ if (err) { -+ usleep_range(EIP93_RING_BUSY_DELAY, -+ EIP93_RING_BUSY_DELAY * 2); -+ goto again; -+ } -+ /* Writing new descriptor count starts DMA action */ -+ writel(1, mtk->base + EIP93_REG_PE_CD_COUNT); -+ -+ ndesc_cdr++; -+ } while (n); -+ -+ return -EINPROGRESS; -+} -+ -+int eip93_send_req(struct crypto_async_request *async, -+ const u8 *reqiv, struct eip93_cipher_reqctx *rctx) -+{ -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm); -+ struct eip93_device *mtk = ctx->mtk; -+ struct scatterlist *src = rctx->sg_src; -+ struct scatterlist *dst = rctx->sg_dst; -+ struct sa_state *sa_state; -+ struct eip93_descriptor cdesc; -+ u32 flags = rctx->flags; -+ int offsetin = 0, err; -+ u32 datalen = rctx->assoclen + rctx->textsize; -+ u32 split = datalen; -+ u32 start, end, ctr, blocks; -+ u32 iv[AES_BLOCK_SIZE / sizeof(u32)]; -+ int crypto_async_idr; -+ -+ rctx->sa_state_ctr = NULL; -+ rctx->sa_state = NULL; -+ -+ if (IS_ECB(flags)) -+ goto skip_iv; -+ -+ memcpy(iv, reqiv, rctx->ivsize); -+ -+ rctx->sa_state = kzalloc(sizeof(*rctx->sa_state), GFP_KERNEL); -+ if (!rctx->sa_state) -+ return -ENOMEM; -+ -+ sa_state = rctx->sa_state; -+ -+ memcpy(sa_state->state_iv, iv, rctx->ivsize); -+ if (IS_RFC3686(flags)) { -+ sa_state->state_iv[0] = ctx->sa_nonce; -+ sa_state->state_iv[1] = iv[0]; -+ sa_state->state_iv[2] = iv[1]; -+ sa_state->state_iv[3] = cpu_to_be32(1); -+ } else if (!IS_HMAC(flags) && IS_CTR(flags)) { -+ /* Compute data length. */ -+ blocks = DIV_ROUND_UP(rctx->textsize, AES_BLOCK_SIZE); -+ ctr = be32_to_cpu(iv[3]); -+ /* Check 32bit counter overflow. */ -+ start = ctr; -+ end = start + blocks - 1; -+ if (end < start) { -+ split = AES_BLOCK_SIZE * -start; -+ /* -+ * Increment the counter manually to cope with -+ * the hardware counter overflow. -+ */ -+ iv[3] = 0xffffffff; -+ crypto_inc((u8 *)iv, AES_BLOCK_SIZE); -+ -+ rctx->sa_state_ctr = kzalloc(sizeof(*rctx->sa_state_ctr), -+ GFP_KERNEL); -+ if (!rctx->sa_state_ctr) -+ goto free_sa_state; -+ -+ memcpy(rctx->sa_state_ctr->state_iv, reqiv, rctx->ivsize); -+ memcpy(sa_state->state_iv, iv, rctx->ivsize); -+ -+ rctx->sa_state_ctr_base = dma_map_single(mtk->dev, rctx->sa_state_ctr, -+ sizeof(*rctx->sa_state_ctr), -+ DMA_TO_DEVICE); -+ err = dma_mapping_error(mtk->dev, rctx->sa_state_ctr_base); -+ if (err) -+ goto free_sa_state_ctr; -+ } -+ } -+ -+ rctx->sa_state_base = dma_map_single(mtk->dev, rctx->sa_state, -+ sizeof(*rctx->sa_state), DMA_TO_DEVICE); -+ err = dma_mapping_error(mtk->dev, rctx->sa_state_base); -+ if (err) -+ goto free_sa_state_ctr_dma; -+ -+skip_iv: -+ -+ cdesc.pe_ctrl_stat_word = FIELD_PREP(EIP93_PE_CTRL_PE_READY_DES_TRING_OWN, -+ EIP93_PE_CTRL_HOST_READY); -+ cdesc.sa_addr = rctx->sa_record_base; -+ cdesc.arc4_addr = 0; -+ -+ scoped_guard(spinlock_bh, &mtk->ring->idr_lock) -+ crypto_async_idr = idr_alloc(&mtk->ring->crypto_async_idr, async, 0, -+ EIP93_RING_NUM - 1, GFP_ATOMIC); -+ -+ cdesc.user_id = FIELD_PREP(EIP93_PE_USER_ID_CRYPTO_IDR, (u16)crypto_async_idr) | -+ FIELD_PREP(EIP93_PE_USER_ID_DESC_FLAGS, rctx->desc_flags); -+ -+ rctx->cdesc = &cdesc; -+ -+ /* map DMA_BIDIRECTIONAL to invalidate cache on destination -+ * implies __dma_cache_wback_inv -+ */ -+ if (!dma_map_sg(mtk->dev, dst, rctx->dst_nents, DMA_BIDIRECTIONAL)) { -+ err = -ENOMEM; -+ goto free_sa_state_ctr_dma; -+ } -+ -+ if (src != dst && -+ !dma_map_sg(mtk->dev, src, rctx->src_nents, DMA_TO_DEVICE)) { -+ err = -ENOMEM; -+ goto free_sg_dma; -+ } -+ -+ return eip93_scatter_combine(mtk, rctx, datalen, split, offsetin); -+ -+free_sg_dma: -+ dma_unmap_sg(mtk->dev, dst, rctx->dst_nents, DMA_BIDIRECTIONAL); -+free_sa_state_ctr_dma: -+ if (rctx->sa_state_ctr) -+ dma_unmap_single(mtk->dev, rctx->sa_state_ctr_base, -+ sizeof(*rctx->sa_state_ctr), -+ DMA_TO_DEVICE); -+free_sa_state_ctr: -+ kfree(rctx->sa_state_ctr); -+ if (rctx->sa_state) -+ dma_unmap_single(mtk->dev, rctx->sa_state_base, -+ sizeof(*rctx->sa_state), -+ DMA_TO_DEVICE); -+free_sa_state: -+ kfree(rctx->sa_state); -+ -+ return err; -+} -+ -+void eip93_unmap_dma(struct eip93_device *mtk, struct eip93_cipher_reqctx *rctx, -+ struct scatterlist *reqsrc, struct scatterlist *reqdst) -+{ -+ u32 len = rctx->assoclen + rctx->textsize; -+ u32 authsize = rctx->authsize; -+ u32 flags = rctx->flags; -+ u32 *otag; -+ int i; -+ -+ if (rctx->sg_src == rctx->sg_dst) { -+ dma_unmap_sg(mtk->dev, rctx->sg_dst, rctx->dst_nents, -+ DMA_BIDIRECTIONAL); -+ goto process_tag; -+ } -+ -+ dma_unmap_sg(mtk->dev, rctx->sg_src, rctx->src_nents, -+ DMA_TO_DEVICE); -+ -+ if (rctx->sg_src != reqsrc) -+ eip93_free_sg_copy(len + rctx->authsize, &rctx->sg_src); -+ -+ dma_unmap_sg(mtk->dev, rctx->sg_dst, rctx->dst_nents, -+ DMA_BIDIRECTIONAL); -+ -+ /* SHA tags need conversion from net-to-host */ -+process_tag: -+ if (IS_DECRYPT(flags)) -+ authsize = 0; -+ -+ if (authsize) { -+ if (!IS_HASH_MD5(flags)) { -+ otag = sg_virt(rctx->sg_dst) + len; -+ for (i = 0; i < (authsize / 4); i++) -+ otag[i] = be32_to_cpu(otag[i]); -+ } -+ } -+ -+ if (rctx->sg_dst != reqdst) { -+ sg_copy_from_buffer(reqdst, sg_nents(reqdst), -+ sg_virt(rctx->sg_dst), len + authsize); -+ eip93_free_sg_copy(len + rctx->authsize, &rctx->sg_dst); -+ } -+} -+ -+void eip93_handle_result(struct eip93_device *mtk, struct eip93_cipher_reqctx *rctx, -+ u8 *reqiv) -+{ -+ if (rctx->sa_state_ctr) -+ dma_unmap_single(mtk->dev, rctx->sa_state_ctr_base, -+ sizeof(*rctx->sa_state_ctr), -+ DMA_FROM_DEVICE); -+ -+ if (rctx->sa_state) -+ dma_unmap_single(mtk->dev, rctx->sa_state_base, -+ sizeof(*rctx->sa_state), -+ DMA_FROM_DEVICE); -+ -+ if (!IS_ECB(rctx->flags)) -+ memcpy(reqiv, rctx->sa_state->state_iv, rctx->ivsize); -+ -+ kfree(rctx->sa_state_ctr); -+ kfree(rctx->sa_state); -+} -+ -+/* basically this is set hmac - key */ -+int eip93_authenc_setkey(struct crypto_aead *aead, struct sa_record *sa, -+ const u8 *authkey, unsigned int authkeylen) -+{ -+ struct crypto_tfm *tfm = crypto_aead_tfm(aead); -+ struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct crypto_ahash *ahash_tfm; -+ struct eip93_hash_reqctx *rctx; -+ struct scatterlist sg[1]; -+ struct ahash_request *req; -+ DECLARE_CRYPTO_WAIT(wait); -+ const char *alg_name; -+ u8 *ipad, *opad; -+ int i, ret; -+ -+ switch ((ctx->flags & EIP93_HASH_MASK)) { -+ case EIP93_HASH_SHA256: -+ alg_name = "sha256-eip93"; -+ break; -+ case EIP93_HASH_SHA224: -+ alg_name = "sha224-eip93"; -+ break; -+ case EIP93_HASH_SHA1: -+ alg_name = "sha1-eip93"; -+ break; -+ case EIP93_HASH_MD5: -+ alg_name = "md5-eip93"; -+ break; -+ default: /* Impossible */ -+ return -EINVAL; -+ } -+ -+ ahash_tfm = crypto_alloc_ahash(alg_name, 0, 0); -+ if (IS_ERR(ahash_tfm)) -+ return PTR_ERR(ahash_tfm); -+ -+ req = ahash_request_alloc(ahash_tfm, GFP_KERNEL); -+ if (!req) { -+ ret = -ENOMEM; -+ goto err_ahash; -+ } -+ -+ ipad = kcalloc(2, SHA256_BLOCK_SIZE, GFP_KERNEL); -+ if (!ipad) { -+ ret = -ENOMEM; -+ goto err_req; -+ } -+ opad = ipad + SHA256_BLOCK_SIZE; -+ -+ rctx = ahash_request_ctx(req); -+ crypto_init_wait(&wait); -+ ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, -+ crypto_req_done, &wait); -+ -+ /* Hash the key if > SHA256_BLOCK_SIZE */ -+ if (authkeylen > SHA256_BLOCK_SIZE) { -+ sg_init_one(&sg[0], authkey, authkeylen); -+ -+ ahash_request_set_crypt(req, sg, ipad, authkeylen); -+ ret = crypto_wait_req(crypto_ahash_digest(req), &wait); -+ -+ authkeylen = ctx->authsize; -+ } else { -+ memcpy(ipad, authkey, authkeylen); -+ } -+ -+ /* Copy to opad */ -+ memset(ipad + authkeylen, 0, SHA256_BLOCK_SIZE - authkeylen); -+ memcpy(opad, ipad, SHA256_BLOCK_SIZE); -+ -+ /* Pad with HMAC constants */ -+ for (i = 0; i < SHA256_BLOCK_SIZE; i++) { -+ ipad[i] ^= HMAC_IPAD_VALUE; -+ opad[i] ^= HMAC_OPAD_VALUE; -+ } -+ -+ /* Disable HASH_FINALIZE for ipad and opad hash */ -+ rctx->no_finalize = true; -+ -+ /* Hash ipad */ -+ sg_init_one(&sg[0], ipad, SHA256_BLOCK_SIZE); -+ ahash_request_set_crypt(req, sg, sa->sa_i_digest, SHA256_BLOCK_SIZE); -+ ret = crypto_ahash_init(req); -+ if (ret) -+ goto exit; -+ -+ /* Disable HASH_FINALIZE for ipad hash */ -+ rctx->no_finalize = true; -+ -+ ret = crypto_wait_req(crypto_ahash_finup(req), &wait); -+ if (ret) -+ goto exit; -+ -+ /* Hash opad */ -+ sg_init_one(&sg[0], opad, SHA256_BLOCK_SIZE); -+ ahash_request_set_crypt(req, sg, sa->sa_o_digest, SHA256_BLOCK_SIZE); -+ ret = crypto_ahash_init(req); -+ if (ret) -+ goto exit; -+ -+ /* Disable HASH_FINALIZE for opad hash */ -+ rctx->no_finalize = true; -+ -+ ret = crypto_wait_req(crypto_ahash_finup(req), &wait); -+ if (ret) -+ goto exit; -+ -+ if (!IS_HASH_MD5(ctx->flags)) { -+ for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(u32); i++) { -+ u32 *ipad_hash = (u32 *)sa->sa_i_digest; -+ u32 *opad_hash = (u32 *)sa->sa_o_digest; -+ -+ ipad_hash[i] = cpu_to_be32(ipad_hash[i]); -+ opad_hash[i] = cpu_to_be32(opad_hash[i]); -+ } -+ } -+ -+exit: -+ kfree(ipad); -+err_req: -+ ahash_request_free(req); -+err_ahash: -+ crypto_free_ahash(ahash_tfm); -+ -+ return ret; -+} ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-common.h -@@ -0,0 +1,25 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -+ * Christian Marangi -+#include -+#include -+#include -+#include -+#include -+ -+#include "eip93-cipher.h" -+#include "eip93-hash.h" -+#include "eip93-main.h" -+#include "eip93-common.h" -+#include "eip93-regs.h" -+ -+static void eip93_hash_free_data_blocks(struct ahash_request *req) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct mkt_hash_block *block; -+ -+ list_for_each_entry(block, &rctx->blocks, list) { -+ dma_unmap_single(rctx->mtk->dev, block->data_dma, -+ SHA256_BLOCK_SIZE, DMA_TO_DEVICE); -+ kfree(block); -+ } -+} -+ -+static void eip93_hash_free_sa_record(struct ahash_request *req) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); -+ struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash); -+ -+ if (IS_HMAC(ctx->flags)) { -+ dma_unmap_single(rctx->mtk->dev, rctx->sa_record_hmac_base, -+ sizeof(*rctx->sa_record_hmac), DMA_TO_DEVICE); -+ kfree(rctx->sa_record_hmac); -+ } -+ -+ dma_unmap_single(rctx->mtk->dev, rctx->sa_record_base, -+ sizeof(*rctx->sa_record), DMA_TO_DEVICE); -+ kfree(rctx->sa_record); -+} -+ -+static void eip93_hash_free_sa_state(struct ahash_request *req) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ -+ dma_unmap_single(rctx->mtk->dev, rctx->sa_state_base, -+ sizeof(*rctx->sa_state), DMA_TO_DEVICE); -+ kfree(rctx->sa_state); -+} -+ -+static struct sa_state *eip93_hash_get_sa_state(struct ahash_request *req, -+ dma_addr_t *sa_state_base) -+{ -+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); -+ struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash); -+ struct eip93_device *mtk = ctx->mtk; -+ struct sa_state *sa_state; -+ int ret; -+ -+ sa_state = kzalloc(sizeof(*sa_state), GFP_KERNEL); -+ if (!sa_state) -+ return ERR_PTR(-ENOMEM); -+ -+ /* Init HASH constant */ -+ switch ((ctx->flags & EIP93_HASH_MASK)) { -+ case EIP93_HASH_SHA256: -+ u32 sha256_init[] = { SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3, -+ SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7 }; -+ -+ memcpy(sa_state->state_i_digest, sha256_init, sizeof(sha256_init)); -+ break; -+ case EIP93_HASH_SHA224: -+ u32 sha224_init[] = { SHA224_H0, SHA224_H1, SHA224_H2, SHA224_H3, -+ SHA224_H4, SHA224_H5, SHA224_H6, SHA224_H7 }; -+ -+ memcpy(sa_state->state_i_digest, sha224_init, sizeof(sha224_init)); -+ break; -+ case EIP93_HASH_SHA1: -+ u32 sha1_init[] = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }; -+ -+ memcpy(sa_state->state_i_digest, sha1_init, sizeof(sha1_init)); -+ break; -+ case EIP93_HASH_MD5: -+ u32 md5_init[] = { MD5_H0, MD5_H1, MD5_H2, MD5_H3 }; -+ -+ memcpy(sa_state->state_i_digest, md5_init, sizeof(md5_init)); -+ break; -+ default: /* Impossible */ -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ *sa_state_base = dma_map_single(mtk->dev, sa_state, -+ sizeof(*sa_state), DMA_TO_DEVICE); -+ ret = dma_mapping_error(mtk->dev, *sa_state_base); -+ if (ret) { -+ kfree(sa_state); -+ return ERR_PTR(ret); -+ } -+ -+ return sa_state; -+} -+ -+static int _eip93_hash_init(struct ahash_request *req, struct sa_state *sa_state, -+ dma_addr_t sa_state_base) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); -+ struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash); -+ struct sa_record *sa_record, *sa_record_hmac; -+ struct eip93_device *mtk = rctx->mtk; -+ int digestsize; -+ int ret; -+ -+ sa_record = kzalloc(sizeof(*sa_record), GFP_KERNEL); -+ if (!sa_record) -+ return -ENOMEM; -+ -+ if (IS_HMAC(ctx->flags)) { -+ sa_record_hmac = kzalloc(sizeof(*sa_record_hmac), GFP_KERNEL); -+ if (!sa_record_hmac) { -+ ret = -ENOMEM; -+ goto free_sa_record; -+ } -+ } -+ -+ digestsize = crypto_ahash_digestsize(ahash); -+ -+ eip93_set_sa_record(sa_record, 0, ctx->flags); -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_HASH_FROM_STATE; -+ sa_record->sa_cmd0_word |= EIP93_SA_CMD_SAVE_HASH; -+ sa_record->sa_cmd0_word &= ~EIP93_SA_CMD_OPCODE; -+ sa_record->sa_cmd0_word |= FIELD_PREP(EIP93_SA_CMD_OPCODE, -+ EIP93_SA_CMD_OPCODE_BASIC_OUT_HASH); -+ sa_record->sa_cmd0_word &= ~EIP93_SA_CMD_DIGEST_LENGTH; -+ sa_record->sa_cmd0_word |= FIELD_PREP(EIP93_SA_CMD_DIGEST_LENGTH, -+ digestsize / sizeof(u32)); -+ -+ /* -+ * HMAC special handling -+ * Enabling CMD_HMAC force the inner hash to be always finalized. -+ * This cause problems on handling message > 64 byte as we -+ * need to produce intermediate inner hash on sending intermediate -+ * 64 bytes blocks. -+ * -+ * To handle this, enable CMD_HMAC only on the last block. -+ * We make a duplicate of sa_record and on the last descriptor, -+ * we pass a dedicated sa_record with CMD_HMAC enabled to make -+ * EIP93 apply the outer hash. -+ */ -+ if (IS_HMAC(ctx->flags)) { -+ memcpy(sa_record_hmac, sa_record, sizeof(*sa_record)); -+ /* Copy pre-hashed opad for HMAC */ -+ memcpy(sa_record_hmac->sa_o_digest, ctx->opad, SHA256_DIGEST_SIZE); -+ -+ /* Disable HMAC for hash normal sa_record */ -+ sa_record->sa_cmd1_word &= ~EIP93_SA_CMD_HMAC; -+ } -+ -+ rctx->mtk = ctx->mtk; -+ rctx->sa_record = sa_record; -+ rctx->sa_record_base = dma_map_single(mtk->dev, rctx->sa_record, -+ sizeof(*rctx->sa_record), -+ DMA_TO_DEVICE); -+ ret = dma_mapping_error(mtk->dev, rctx->sa_record_base); -+ if (ret) -+ goto free_sa_record; -+ -+ if (IS_HMAC(ctx->flags)) { -+ rctx->sa_record_hmac = sa_record_hmac; -+ rctx->sa_record_hmac_base = dma_map_single(mtk->dev, -+ rctx->sa_record_hmac, -+ sizeof(*rctx->sa_record_hmac), -+ DMA_TO_DEVICE); -+ ret = dma_mapping_error(mtk->dev, rctx->sa_record_hmac_base); -+ if (ret) -+ goto free_sa_record_base; -+ } -+ -+ rctx->sa_state = sa_state; -+ rctx->sa_state_base = sa_state_base; -+ -+ rctx->len = 0; -+ rctx->left_last = 0; -+ rctx->no_finalize = false; -+ INIT_LIST_HEAD(&rctx->blocks); -+ -+ return 0; -+ -+free_sa_record_base: -+ dma_unmap_single(mtk->dev, rctx->sa_record_base, sizeof(*rctx->sa_record), -+ DMA_TO_DEVICE); -+free_sa_record: -+ kfree(sa_record); -+ return ret; -+} -+ -+static int eip93_hash_init(struct ahash_request *req) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); -+ struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash); -+ struct sa_state *sa_state; -+ dma_addr_t sa_state_base; -+ int ret; -+ -+ sa_state = eip93_hash_get_sa_state(req, &sa_state_base); -+ if (IS_ERR(sa_state)) -+ return PTR_ERR(sa_state); -+ -+ ret = _eip93_hash_init(req, sa_state, sa_state_base); -+ if (ret) -+ eip93_hash_free_sa_state(req); -+ -+ /* For HMAC setup the initial block for ipad */ -+ if (IS_HMAC(ctx->flags)) { -+ struct mkt_hash_block *block; -+ -+ block = kzalloc(sizeof(*block), GFP_KERNEL); -+ if (!block) { -+ eip93_hash_free_sa_record(req); -+ eip93_hash_free_sa_state(req); -+ return -ENOMEM; -+ } -+ -+ memcpy(block->data, ctx->ipad, SHA256_BLOCK_SIZE); -+ -+ list_add(&block->list, &rctx->blocks); -+ -+ rctx->len += SHA256_BLOCK_SIZE; -+ } -+ -+ return ret; -+} -+ -+static void eip93_send_hash_req(struct crypto_async_request *async, dma_addr_t src_addr, -+ u32 len, bool last) -+{ -+ struct ahash_request *req = ahash_request_cast(async); -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); -+ struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash); -+ struct eip93_device *mtk = rctx->mtk; -+ struct eip93_descriptor cdesc = { }; -+ int ret; -+ -+ cdesc.pe_ctrl_stat_word = FIELD_PREP(EIP93_PE_CTRL_PE_READY_DES_TRING_OWN, -+ EIP93_PE_CTRL_HOST_READY); -+ cdesc.sa_addr = rctx->sa_record_base; -+ cdesc.arc4_addr = 0; -+ -+ cdesc.state_addr = rctx->sa_state_base; -+ cdesc.src_addr = src_addr; -+ cdesc.pe_length_word = FIELD_PREP(EIP93_PE_LENGTH_HOST_PE_READY, -+ EIP93_PE_LENGTH_HOST_READY); -+ cdesc.pe_length_word |= FIELD_PREP(EIP93_PE_LENGTH_LENGTH, -+ len); -+ -+ cdesc.user_id |= FIELD_PREP(EIP93_PE_USER_ID_DESC_FLAGS, EIP93_DESC_HASH); -+ -+ if (last) { -+ int crypto_async_idr; -+ -+ /* For last block, pass sa_record with CMD_HMAC enabled */ -+ if (IS_HMAC(ctx->flags)) -+ cdesc.sa_addr = rctx->sa_record_hmac_base; -+ -+ if (!rctx->no_finalize) -+ cdesc.pe_ctrl_stat_word |= EIP93_PE_CTRL_PE_HASH_FINAL; -+ -+ scoped_guard(spinlock_bh, &mtk->ring->idr_lock) -+ crypto_async_idr = idr_alloc(&mtk->ring->crypto_async_idr, async, 0, -+ EIP93_RING_NUM - 1, GFP_ATOMIC); -+ -+ cdesc.user_id |= FIELD_PREP(EIP93_PE_USER_ID_CRYPTO_IDR, (u16)crypto_async_idr) | -+ FIELD_PREP(EIP93_PE_USER_ID_DESC_FLAGS, EIP93_DESC_LAST); -+ } -+ -+again: -+ ret = eip93_put_descriptor(mtk, &cdesc); -+ if (ret) { -+ usleep_range(EIP93_RING_BUSY_DELAY, -+ EIP93_RING_BUSY_DELAY * 2); -+ goto again; -+ } -+ -+ /* Writing new descriptor count starts DMA action */ -+ writel(1, mtk->base + EIP93_REG_PE_CD_COUNT); -+} -+ -+static int eip93_hash_update(struct ahash_request *req) -+{ -+ struct crypto_async_request *async = &req->base; -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ unsigned int to_consume = req->nbytes; -+ struct eip93_device *mtk = rctx->mtk; -+ struct mkt_hash_block *block; -+ int read = 0; -+ int ret; -+ -+ /* If the request is 0 length, do nothing */ -+ if (!to_consume) -+ return 0; -+ -+ /* -+ * Check if we are at a second iteration. -+ * 1. Try to fill the first block to 64byte (if not already) -+ * 2. Send full block (if we have more data to consume) -+ */ -+ if (rctx->len > 0) { -+ int offset = SHA256_BLOCK_SIZE - rctx->left_last; -+ -+ block = list_first_entry(&rctx->blocks, -+ struct mkt_hash_block, list); -+ -+ /* Fill the first block */ -+ if (rctx->left_last) { -+ read += sg_pcopy_to_buffer(req->src, sg_nents(req->src), -+ block->data + offset, -+ min(to_consume, rctx->left_last), -+ 0); -+ to_consume -= read; -+ rctx->left_last -= read; -+ } -+ -+ /* Send descriptor if we have more data to consume */ -+ if (to_consume > 0) { -+ block->data_dma = dma_map_single(mtk->dev, block->data, -+ SHA256_BLOCK_SIZE, -+ DMA_TO_DEVICE); -+ ret = dma_mapping_error(mtk->dev, block->data_dma); -+ if (ret) -+ return ret; -+ -+ eip93_send_hash_req(async, block->data_dma, -+ SHA256_BLOCK_SIZE, false); -+ } -+ } -+ -+ /* -+ * Consume remaining data. -+ * 1. Loop until we consume all the data in block of 64bytes -+ * 2. Send full block of 64bytes -+ * 3. Skip sending last block for future update() or for final() to -+ * enable HASH_FINALIZE bit. -+ */ -+ while (to_consume > 0) { -+ int to_read = min(to_consume, SHA256_BLOCK_SIZE); -+ -+ block = kzalloc(sizeof(*block), GFP_KERNEL); -+ if (!block) -+ return -ENOMEM; -+ -+ read += sg_pcopy_to_buffer(req->src, sg_nents(req->src), -+ block->data, to_read, -+ read); -+ -+ list_add(&block->list, &rctx->blocks); -+ -+ to_consume -= to_read; -+ rctx->left_last = SHA256_BLOCK_SIZE - to_read; -+ -+ /* Send descriptor if we have more data to consume */ -+ if (to_consume > 0) { -+ block->data_dma = dma_map_single(mtk->dev, block->data, -+ SHA256_BLOCK_SIZE, -+ DMA_TO_DEVICE); -+ ret = dma_mapping_error(mtk->dev, block->data_dma); -+ if (ret) -+ return ret; -+ -+ eip93_send_hash_req(async, block->data_dma, -+ SHA256_BLOCK_SIZE, false); -+ } -+ } -+ -+ /* -+ * Update counter with processed bytes. -+ * This is also used to check if we are at the second iteration -+ * of an update(). -+ */ -+ rctx->len += req->nbytes; -+ -+ return 0; -+} -+ -+void eip93_hash_handle_result(struct crypto_async_request *async, int err) -+{ -+ struct ahash_request *req = ahash_request_cast(async); -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); -+ struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash); -+ int digestsize = crypto_ahash_digestsize(ahash); -+ struct sa_state *sa_state = rctx->sa_state; -+ int i; -+ -+ /* Unmap and sync sa_state for host */ -+ dma_unmap_single(rctx->mtk->dev, rctx->sa_state_base, -+ sizeof(*sa_state), DMA_FROM_DEVICE); -+ -+ /* -+ * With no_finalize assume SHA256_DIGEST_SIZE buffer is passed. -+ * This is to handle SHA224 that have a 32 byte intermediate digest. -+ */ -+ if (rctx->no_finalize) -+ digestsize = SHA256_DIGEST_SIZE; -+ -+ /* bytes needs to be swapped for req->result */ -+ if (!IS_HASH_MD5(ctx->flags)) { -+ for (i = 0; i < digestsize / sizeof(u32); i++) { -+ u32 *digest = (u32 *)sa_state->state_i_digest; -+ -+ digest[i] = be32_to_cpu(digest[i]); -+ } -+ } -+ -+ memcpy(req->result, sa_state->state_i_digest, digestsize); -+ -+ kfree(sa_state); -+ eip93_hash_free_data_blocks(req); -+ eip93_hash_free_sa_record(req); -+ -+ ahash_request_complete(req, err); -+} -+ -+static int eip93_hash_final(struct ahash_request *req) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); -+ struct eip93_hash_ctx *ctx = crypto_ahash_ctx(ahash); -+ struct crypto_async_request *async = &req->base; -+ struct eip93_device *mtk = rctx->mtk; -+ struct mkt_hash_block *block; -+ int ret; -+ -+ /* EIP93 can't handle zero bytes hash */ -+ if (!rctx->len && !IS_HMAC(ctx->flags)) { -+ switch ((ctx->flags & EIP93_HASH_MASK)) { -+ case EIP93_HASH_SHA256: -+ memcpy(req->result, sha256_zero_message_hash, -+ SHA256_DIGEST_SIZE); -+ break; -+ case EIP93_HASH_SHA224: -+ memcpy(req->result, sha224_zero_message_hash, -+ SHA224_DIGEST_SIZE); -+ break; -+ case EIP93_HASH_SHA1: -+ memcpy(req->result, sha1_zero_message_hash, -+ SHA1_DIGEST_SIZE); -+ break; -+ case EIP93_HASH_MD5: -+ memcpy(req->result, md5_zero_message_hash, -+ MD5_DIGEST_SIZE); -+ break; -+ default: /* Impossible */ -+ return -EINVAL; -+ } -+ -+ eip93_hash_free_sa_state(req); -+ eip93_hash_free_sa_record(req); -+ -+ return 0; -+ } -+ -+ /* Send last block */ -+ block = list_first_entry(&rctx->blocks, struct mkt_hash_block, list); -+ -+ block->data_dma = dma_map_single(mtk->dev, block->data, -+ SHA256_BLOCK_SIZE, DMA_TO_DEVICE); -+ ret = dma_mapping_error(mtk->dev, block->data_dma); -+ if (ret) -+ return ret; -+ -+ eip93_send_hash_req(async, block->data_dma, -+ SHA256_BLOCK_SIZE - rctx->left_last, -+ true); -+ -+ return -EINPROGRESS; -+} -+ -+static int eip93_hash_finup(struct ahash_request *req) -+{ -+ int ret; -+ -+ ret = eip93_hash_update(req); -+ if (ret) -+ return ret; -+ -+ return eip93_hash_final(req); -+} -+ -+static int eip93_hash_hmac_setkey(struct crypto_ahash *ahash, const u8 *key, -+ u32 keylen) -+{ -+ unsigned int digestsize = crypto_ahash_digestsize(ahash); -+ struct crypto_tfm *tfm = crypto_ahash_tfm(ahash); -+ struct eip93_hash_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct crypto_ahash *ahash_tfm; -+ struct eip93_hash_reqctx *rctx; -+ struct scatterlist sg[1]; -+ struct ahash_request *req; -+ DECLARE_CRYPTO_WAIT(wait); -+ const char *alg_name; -+ int i, ret = 0; -+ u8 *opad; -+ -+ switch ((ctx->flags & EIP93_HASH_MASK)) { -+ case EIP93_HASH_SHA256: -+ alg_name = "sha256-eip93"; -+ break; -+ case EIP93_HASH_SHA224: -+ alg_name = "sha224-eip93"; -+ break; -+ case EIP93_HASH_SHA1: -+ alg_name = "sha1-eip93"; -+ break; -+ case EIP93_HASH_MD5: -+ alg_name = "md5-eip93"; -+ break; -+ default: /* Impossible */ -+ return -EINVAL; -+ } -+ -+ ahash_tfm = crypto_alloc_ahash(alg_name, 0, 0); -+ if (IS_ERR(ahash_tfm)) -+ return PTR_ERR(ahash_tfm); -+ -+ req = ahash_request_alloc(ahash_tfm, GFP_KERNEL); -+ if (!req) { -+ ret = -ENOMEM; -+ goto err_ahash; -+ } -+ -+ opad = kzalloc(SHA256_BLOCK_SIZE, GFP_KERNEL); -+ if (!opad) { -+ ret = -ENOMEM; -+ goto err_req; -+ } -+ -+ rctx = ahash_request_ctx(req); -+ crypto_init_wait(&wait); -+ ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, -+ crypto_req_done, &wait); -+ -+ /* Hash the key if > SHA256_BLOCK_SIZE */ -+ if (keylen > SHA256_BLOCK_SIZE) { -+ sg_init_one(&sg[0], key, keylen); -+ -+ ahash_request_set_crypt(req, sg, ctx->ipad, keylen); -+ ret = crypto_wait_req(crypto_ahash_digest(req), &wait); -+ -+ keylen = digestsize; -+ } else { -+ memcpy(ctx->ipad, key, keylen); -+ } -+ -+ /* Copy to opad */ -+ memset(ctx->ipad + keylen, 0, SHA256_BLOCK_SIZE - keylen); -+ memcpy(opad, ctx->ipad, SHA256_BLOCK_SIZE); -+ -+ /* Pad with HMAC constants */ -+ for (i = 0; i < SHA256_BLOCK_SIZE; i++) { -+ ctx->ipad[i] ^= HMAC_IPAD_VALUE; -+ opad[i] ^= HMAC_OPAD_VALUE; -+ } -+ -+ sg_init_one(&sg[0], opad, SHA256_BLOCK_SIZE); -+ -+ /* Hash opad */ -+ ahash_request_set_crypt(req, sg, ctx->opad, SHA256_BLOCK_SIZE); -+ ret = crypto_ahash_init(req); -+ if (ret) -+ goto exit; -+ -+ /* Disable HASH_FINALIZE for opad hash */ -+ rctx->no_finalize = true; -+ -+ ret = crypto_wait_req(crypto_ahash_finup(req), &wait); -+ if (ret) -+ goto exit; -+ -+ if (!IS_HASH_MD5(ctx->flags)) { -+ u32 *opad_hash = (u32 *)ctx->opad; -+ -+ for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(u32); i++) -+ opad_hash[i] = cpu_to_be32(opad_hash[i]); -+ } -+ -+exit: -+ kfree(opad); -+err_req: -+ ahash_request_free(req); -+err_ahash: -+ crypto_free_ahash(ahash_tfm); -+ -+ return ret; -+} -+ -+static int eip93_hash_cra_init(struct crypto_tfm *tfm) -+{ -+ struct eip93_hash_ctx *ctx = crypto_tfm_ctx(tfm); -+ struct eip93_alg_template *tmpl = container_of(tfm->__crt_alg, -+ struct eip93_alg_template, alg.ahash.halg.base); -+ -+ crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), -+ sizeof(struct eip93_hash_reqctx)); -+ -+ ctx->mtk = tmpl->mtk; -+ ctx->flags = tmpl->flags; -+ -+ return 0; -+} -+ -+static int eip93_hash_digest(struct ahash_request *req) -+{ -+ int ret; -+ -+ ret = eip93_hash_init(req); -+ if (ret) -+ return ret; -+ -+ return eip93_hash_finup(req); -+} -+ -+static int eip93_hash_import(struct ahash_request *req, const void *in) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ const struct eip93_hash_export_state *state = in; -+ int ret; -+ -+ ret = _eip93_hash_init(req, state->sa_state, state->sa_state_base); -+ if (ret) -+ goto err; -+ -+ rctx->len = state->len; -+ rctx->left_last = state->left_last; -+ memcpy(&rctx->blocks, &state->blocks, sizeof(rctx->blocks)); -+ -+ return 0; -+err: -+ eip93_hash_free_data_blocks(req); -+ eip93_hash_free_sa_state(req); -+ return ret; -+} -+ -+static int eip93_hash_export(struct ahash_request *req, void *out) -+{ -+ struct eip93_hash_reqctx *rctx = ahash_request_ctx(req); -+ struct eip93_hash_export_state *state = out; -+ -+ state->sa_state = rctx->sa_state; -+ state->sa_state_base = rctx->sa_state_base; -+ state->len = rctx->len; -+ state->left_last = rctx->left_last; -+ memcpy(&state->blocks, &rctx->blocks, sizeof(rctx->blocks)); -+ -+ return 0; -+} -+ -+struct eip93_alg_template eip93_alg_md5 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_MD5, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = MD5_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "md5", -+ .cra_driver_name = "md5-eip93", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_sha1 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_SHA1, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = SHA1_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "sha1", -+ .cra_driver_name = "sha1-eip93", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = SHA1_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_sha224 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_SHA224, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = SHA224_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "sha224", -+ .cra_driver_name = "sha224-eip93", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = SHA224_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_sha256 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_SHA256, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = SHA256_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "sha256", -+ .cra_driver_name = "sha256-eip93", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = SHA256_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_hmac_md5 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_MD5, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .setkey = eip93_hash_hmac_setkey, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = MD5_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "hmac(md5)", -+ .cra_driver_name = "hmac(md5-eip93)", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_hmac_sha1 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA1, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .setkey = eip93_hash_hmac_setkey, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = SHA1_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "hmac(sha1)", -+ .cra_driver_name = "hmac(sha1-eip93)", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = SHA1_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_hmac_sha224 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA224, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .setkey = eip93_hash_hmac_setkey, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = SHA224_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "hmac(sha224)", -+ .cra_driver_name = "hmac(sha224-eip93)", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = SHA224_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; -+ -+struct eip93_alg_template eip93_alg_hmac_sha256 = { -+ .type = EIP93_ALG_TYPE_HASH, -+ .flags = EIP93_HASH_HMAC | EIP93_HASH_SHA256, -+ .alg.ahash = { -+ .init = eip93_hash_init, -+ .update = eip93_hash_update, -+ .final = eip93_hash_final, -+ .finup = eip93_hash_finup, -+ .digest = eip93_hash_digest, -+ .setkey = eip93_hash_hmac_setkey, -+ .export = eip93_hash_export, -+ .import = eip93_hash_import, -+ .halg = { -+ .digestsize = SHA256_DIGEST_SIZE, -+ .statesize = sizeof(struct eip93_hash_export_state), -+ .base = { -+ .cra_name = "hmac(sha256)", -+ .cra_driver_name = "hmac(sha256-eip93)", -+ .cra_priority = 300, -+ .cra_flags = CRYPTO_ALG_ASYNC | -+ CRYPTO_ALG_KERN_DRIVER_ONLY | -+ CRYPTO_ALG_ALLOCATES_MEMORY, -+ .cra_blocksize = SHA256_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct eip93_hash_ctx), -+ .cra_init = eip93_hash_cra_init, -+ .cra_module = THIS_MODULE, -+ }, -+ }, -+ }, -+}; ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-hash.h -@@ -0,0 +1,72 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -+ -+#include "eip93-main.h" -+ -+struct eip93_hash_ctx { -+ struct eip93_device *mtk; -+ u32 flags; -+ -+ u8 ipad[SHA256_BLOCK_SIZE] __aligned(sizeof(u32)); -+ u8 opad[SHA256_DIGEST_SIZE] __aligned(sizeof(u32)); -+}; -+ -+struct eip93_hash_reqctx { -+ struct eip93_device *mtk; -+ -+ struct sa_record *sa_record; -+ dma_addr_t sa_record_base; -+ -+ struct sa_record *sa_record_hmac; -+ dma_addr_t sa_record_hmac_base; -+ -+ struct sa_state *sa_state; -+ dma_addr_t sa_state_base; -+ -+ /* Don't enable HASH_FINALIZE when last block is sent */ -+ bool no_finalize; -+ -+ /* -+ * EIP93 requires data to be accumulated in block of 64 bytes -+ * for intermediate hash calculation. -+ */ -+ u64 len; -+ u32 left_last; -+ struct list_head blocks; -+}; -+ -+struct mkt_hash_block { -+ struct list_head list; -+ u8 data[SHA256_BLOCK_SIZE] __aligned(sizeof(u32)); -+ dma_addr_t data_dma; -+}; -+ -+struct eip93_hash_export_state { -+ u64 len; -+ u32 left_last; -+ struct sa_state *sa_state; -+ dma_addr_t sa_state_base; -+ struct list_head blocks; -+}; -+ -+void eip93_hash_handle_result(struct crypto_async_request *async, int err); -+ -+extern struct eip93_alg_template eip93_alg_md5; -+extern struct eip93_alg_template eip93_alg_sha1; -+extern struct eip93_alg_template eip93_alg_sha224; -+extern struct eip93_alg_template eip93_alg_sha256; -+extern struct eip93_alg_template eip93_alg_hmac_md5; -+extern struct eip93_alg_template eip93_alg_hmac_sha1; -+extern struct eip93_alg_template eip93_alg_hmac_sha224; -+extern struct eip93_alg_template eip93_alg_hmac_sha256; -+ -+#endif /* _EIP93_HASH_H_ */ ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-main.c -@@ -0,0 +1,502 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "eip93-main.h" -+#include "eip93-regs.h" -+#include "eip93-common.h" -+#include "eip93-cipher.h" -+#include "eip93-aes.h" -+#include "eip93-des.h" -+#include "eip93-aead.h" -+#include "eip93-hash.h" -+ -+static struct eip93_alg_template *eip93_algs[] = { -+ &eip93_alg_ecb_des, -+ &eip93_alg_cbc_des, -+ &eip93_alg_ecb_des3_ede, -+ &eip93_alg_cbc_des3_ede, -+ &eip93_alg_ecb_aes, -+ &eip93_alg_cbc_aes, -+ &eip93_alg_ctr_aes, -+ &eip93_alg_rfc3686_aes, -+ &eip93_alg_authenc_hmac_md5_cbc_des, -+ &eip93_alg_authenc_hmac_sha1_cbc_des, -+ &eip93_alg_authenc_hmac_sha224_cbc_des, -+ &eip93_alg_authenc_hmac_sha256_cbc_des, -+ &eip93_alg_authenc_hmac_md5_cbc_des3_ede, -+ &eip93_alg_authenc_hmac_sha1_cbc_des3_ede, -+ &eip93_alg_authenc_hmac_sha224_cbc_des3_ede, -+ &eip93_alg_authenc_hmac_sha256_cbc_des3_ede, -+ &eip93_alg_authenc_hmac_md5_cbc_aes, -+ &eip93_alg_authenc_hmac_sha1_cbc_aes, -+ &eip93_alg_authenc_hmac_sha224_cbc_aes, -+ &eip93_alg_authenc_hmac_sha256_cbc_aes, -+ &eip93_alg_authenc_hmac_md5_rfc3686_aes, -+ &eip93_alg_authenc_hmac_sha1_rfc3686_aes, -+ &eip93_alg_authenc_hmac_sha224_rfc3686_aes, -+ &eip93_alg_authenc_hmac_sha256_rfc3686_aes, -+ &eip93_alg_md5, -+ &eip93_alg_sha1, -+ &eip93_alg_sha224, -+ &eip93_alg_sha256, -+ &eip93_alg_hmac_md5, -+ &eip93_alg_hmac_sha1, -+ &eip93_alg_hmac_sha224, -+ &eip93_alg_hmac_sha256, -+}; -+ -+inline void eip93_irq_disable(struct eip93_device *mtk, u32 mask) -+{ -+ __raw_writel(mask, mtk->base + EIP93_REG_MASK_DISABLE); -+} -+ -+inline void eip93_irq_enable(struct eip93_device *mtk, u32 mask) -+{ -+ __raw_writel(mask, mtk->base + EIP93_REG_MASK_ENABLE); -+} -+ -+inline void eip93_irq_clear(struct eip93_device *mtk, u32 mask) -+{ -+ __raw_writel(mask, mtk->base + EIP93_REG_INT_CLR); -+} -+ -+static void eip93_unregister_algs(unsigned int i) -+{ -+ unsigned int j; -+ -+ for (j = 0; j < i; j++) { -+ switch (eip93_algs[j]->type) { -+ case EIP93_ALG_TYPE_SKCIPHER: -+ crypto_unregister_skcipher(&eip93_algs[j]->alg.skcipher); -+ break; -+ case EIP93_ALG_TYPE_AEAD: -+ crypto_unregister_aead(&eip93_algs[j]->alg.aead); -+ break; -+ case EIP93_ALG_TYPE_HASH: -+ crypto_unregister_ahash(&eip93_algs[i]->alg.ahash); -+ break; -+ } -+ } -+} -+ -+static int eip93_register_algs(struct eip93_device *mtk, u32 supported_algo_flags) -+{ -+ unsigned int i; -+ int ret = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(eip93_algs); i++) { -+ u32 alg_flags = eip93_algs[i]->flags; -+ -+ eip93_algs[i]->mtk = mtk; -+ -+ if ((IS_DES(alg_flags) || IS_3DES(alg_flags)) && -+ !(supported_algo_flags & EIP93_PE_OPTION_TDES)) -+ continue; -+ -+ if (IS_AES(alg_flags)) { -+ if (!(supported_algo_flags & EIP93_PE_OPTION_AES)) -+ continue; -+ -+ if (!IS_HMAC(alg_flags)) { -+ if (supported_algo_flags & EIP93_PE_OPTION_AES_KEY128) -+ eip93_algs[i]->alg.skcipher.max_keysize = -+ AES_KEYSIZE_128; -+ -+ if (supported_algo_flags & EIP93_PE_OPTION_AES_KEY192) -+ eip93_algs[i]->alg.skcipher.max_keysize = -+ AES_KEYSIZE_192; -+ -+ if (supported_algo_flags & EIP93_PE_OPTION_AES_KEY256) -+ eip93_algs[i]->alg.skcipher.max_keysize = -+ AES_KEYSIZE_256; -+ -+ if (IS_RFC3686(alg_flags)) -+ eip93_algs[i]->alg.skcipher.max_keysize += -+ CTR_RFC3686_NONCE_SIZE; -+ } -+ } -+ -+ if (IS_HASH_MD5(alg_flags) && -+ !(supported_algo_flags & EIP93_PE_OPTION_MD5)) -+ continue; -+ -+ if (IS_HASH_SHA1(alg_flags) && -+ !(supported_algo_flags & EIP93_PE_OPTION_SHA_1)) -+ continue; -+ -+ if (IS_HASH_SHA224(alg_flags) && -+ !(supported_algo_flags & EIP93_PE_OPTION_SHA_224)) -+ continue; -+ -+ if (IS_HASH_SHA256(alg_flags) && -+ !(supported_algo_flags & EIP93_PE_OPTION_SHA_256)) -+ continue; -+ -+ switch (eip93_algs[i]->type) { -+ case EIP93_ALG_TYPE_SKCIPHER: -+ ret = crypto_register_skcipher(&eip93_algs[i]->alg.skcipher); -+ break; -+ case EIP93_ALG_TYPE_AEAD: -+ ret = crypto_register_aead(&eip93_algs[i]->alg.aead); -+ break; -+ case EIP93_ALG_TYPE_HASH: -+ ret = crypto_register_ahash(&eip93_algs[i]->alg.ahash); -+ break; -+ } -+ if (ret) -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ eip93_unregister_algs(i); -+ -+ return ret; -+} -+ -+static void eip93_handle_result_descriptor(struct eip93_device *mtk) -+{ -+ struct crypto_async_request *async; -+ struct eip93_descriptor *rdesc; -+ u16 desc_flags, crypto_idr; -+ bool last_entry; -+ int handled, left, err; -+ u32 pe_ctrl_stat; -+ u32 pe_length; -+ -+get_more: -+ handled = 0; -+ -+ left = readl(mtk->base + EIP93_REG_PE_RD_COUNT) & EIP93_PE_RD_COUNT; -+ -+ if (!left) { -+ eip93_irq_clear(mtk, EIP93_INT_RDR_THRESH); -+ eip93_irq_enable(mtk, EIP93_INT_RDR_THRESH); -+ return; -+ } -+ -+ last_entry = false; -+ -+ while (left) { -+ rdesc = eip93_get_descriptor(mtk); -+ if (IS_ERR(rdesc)) { -+ dev_err(mtk->dev, "Ndesc: %d nreq: %d\n", -+ handled, left); -+ err = -EIO; -+ break; -+ } -+ /* make sure DMA is finished writing */ -+ do { -+ pe_ctrl_stat = READ_ONCE(rdesc->pe_ctrl_stat_word); -+ pe_length = READ_ONCE(rdesc->pe_length_word); -+ } while (FIELD_GET(EIP93_PE_CTRL_PE_READY_DES_TRING_OWN, pe_ctrl_stat) != -+ EIP93_PE_CTRL_PE_READY || -+ FIELD_GET(EIP93_PE_LENGTH_HOST_PE_READY, pe_length) != -+ EIP93_PE_LENGTH_PE_READY); -+ -+ err = rdesc->pe_ctrl_stat_word & (EIP93_PE_CTRL_PE_EXT_ERR_CODE | -+ EIP93_PE_CTRL_PE_EXT_ERR | -+ EIP93_PE_CTRL_PE_SEQNUM_ERR | -+ EIP93_PE_CTRL_PE_PAD_ERR | -+ EIP93_PE_CTRL_PE_AUTH_ERR); -+ -+ desc_flags = FIELD_GET(EIP93_PE_USER_ID_DESC_FLAGS, rdesc->user_id); -+ crypto_idr = FIELD_GET(EIP93_PE_USER_ID_CRYPTO_IDR, rdesc->user_id); -+ -+ writel(1, mtk->base + EIP93_REG_PE_RD_COUNT); -+ eip93_irq_clear(mtk, EIP93_INT_RDR_THRESH); -+ -+ handled++; -+ left--; -+ -+ if (desc_flags & EIP93_DESC_LAST) { -+ last_entry = true; -+ break; -+ } -+ } -+ -+ if (!last_entry) -+ goto get_more; -+ -+ /* Get crypto async ref only for last descriptor */ -+ scoped_guard(spinlock_bh, &mtk->ring->idr_lock) { -+ async = idr_find(&mtk->ring->crypto_async_idr, crypto_idr); -+ idr_remove(&mtk->ring->crypto_async_idr, crypto_idr); -+ } -+ -+ /* Parse error in ctrl stat word */ -+ err = eip93_parse_ctrl_stat_err(mtk, err); -+ -+ if (desc_flags & EIP93_DESC_SKCIPHER) -+ eip93_skcipher_handle_result(async, err); -+ -+ if (desc_flags & EIP93_DESC_AEAD) -+ eip93_aead_handle_result(async, err); -+ -+ if (desc_flags & EIP93_DESC_HASH) -+ eip93_hash_handle_result(async, err); -+ -+ goto get_more; -+} -+ -+static void eip93_done_task(unsigned long data) -+{ -+ struct eip93_device *mtk = (struct eip93_device *)data; -+ -+ eip93_handle_result_descriptor(mtk); -+} -+ -+static irqreturn_t eip93_irq_handler(int irq, void *data) -+{ -+ struct eip93_device *mtk = data; -+ u32 irq_status; -+ -+ irq_status = readl(mtk->base + EIP93_REG_INT_MASK_STAT); -+ if (FIELD_GET(EIP93_INT_RDR_THRESH, irq_status)) { -+ eip93_irq_disable(mtk, EIP93_INT_RDR_THRESH); -+ tasklet_schedule(&mtk->ring->done_task); -+ return IRQ_HANDLED; -+ } -+ -+ /* Ignore errors in AUTO mode, handled by the RDR */ -+ eip93_irq_clear(mtk, irq_status); -+ if (irq_status) -+ eip93_irq_disable(mtk, irq_status); -+ -+ return IRQ_NONE; -+} -+ -+static void eip93_initialize(struct eip93_device *mtk, u32 supported_algo_flags) -+{ -+ u32 val; -+ -+ /* Reset PE and rings */ -+ val = EIP93_PE_CONFIG_RST_PE | EIP93_PE_CONFIG_RST_RING; -+ val |= EIP93_PE_TARGET_AUTO_RING_MODE; -+ /* For Auto more, update the CDR ring owner after processing */ -+ val |= EIP93_PE_CONFIG_EN_CDR_UPDATE; -+ writel(val, mtk->base + EIP93_REG_PE_CONFIG); -+ -+ /* Wait for PE and ring to reset */ -+ usleep_range(10, 20); -+ -+ /* Release PE and ring reset */ -+ val = readl(mtk->base + EIP93_REG_PE_CONFIG); -+ val &= ~(EIP93_PE_CONFIG_RST_PE | EIP93_PE_CONFIG_RST_RING); -+ writel(val, mtk->base + EIP93_REG_PE_CONFIG); -+ -+ /* Config Clocks */ -+ val = EIP93_PE_CLOCK_EN_PE_CLK; -+ if (supported_algo_flags & EIP93_PE_OPTION_TDES) -+ val |= EIP93_PE_CLOCK_EN_DES_CLK; -+ if (supported_algo_flags & EIP93_PE_OPTION_AES) -+ val |= EIP93_PE_CLOCK_EN_AES_CLK; -+ if (supported_algo_flags & -+ (EIP93_PE_OPTION_MD5 | EIP93_PE_OPTION_SHA_1 | EIP93_PE_OPTION_SHA_224 | -+ EIP93_PE_OPTION_SHA_256)) -+ val |= EIP93_PE_CLOCK_EN_HASH_CLK; -+ writel(val, mtk->base + EIP93_REG_PE_CLOCK_CTRL); -+ -+ /* Config DMA thresholds */ -+ val = FIELD_PREP(EIP93_PE_OUTBUF_THRESH, 128) | -+ FIELD_PREP(EIP93_PE_INBUF_THRESH, 128); -+ writel(val, mtk->base + EIP93_REG_PE_BUF_THRESH); -+ -+ /* Clear/ack all interrupts before disable all */ -+ eip93_irq_clear(mtk, EIP93_INT_ALL); -+ eip93_irq_disable(mtk, EIP93_INT_ALL); -+ -+ /* Setup CRD threshold to trigger interrupt */ -+ val = FIELD_PREP(EIPR93_PE_CDR_THRESH, EIP93_RING_NUM - EIP93_RING_BUSY); -+ /* -+ * Configure RDR interrupt to be triggered if RD counter is not 0 -+ * for more than 2^(N+10) system clocks. -+ */ -+ val |= FIELD_PREP(EIPR93_PE_RD_TIMEOUT, 5) | EIPR93_PE_TIMEROUT_EN; -+ writel(val, mtk->base + EIP93_REG_PE_RING_THRESH); -+} -+ -+static void eip93_desc_free(struct eip93_device *mtk) -+{ -+ writel(0, mtk->base + EIP93_REG_PE_RING_CONFIG); -+ writel(0, mtk->base + EIP93_REG_PE_CDR_BASE); -+ writel(0, mtk->base + EIP93_REG_PE_RDR_BASE); -+} -+ -+static int eip93_set_ring(struct eip93_device *mtk, struct eip93_desc_ring *ring) -+{ -+ ring->offset = sizeof(struct eip93_descriptor); -+ ring->base = dmam_alloc_coherent(mtk->dev, -+ sizeof(struct eip93_descriptor) * EIP93_RING_NUM, -+ &ring->base_dma, GFP_KERNEL); -+ if (!ring->base) -+ return -ENOMEM; -+ -+ ring->write = ring->base; -+ ring->base_end = ring->base + sizeof(struct eip93_descriptor) * (EIP93_RING_NUM - 1); -+ ring->read = ring->base; -+ -+ return 0; -+} -+ -+static int eip93_desc_init(struct eip93_device *mtk) -+{ -+ struct eip93_desc_ring *cdr = &mtk->ring->cdr; -+ struct eip93_desc_ring *rdr = &mtk->ring->rdr; -+ int ret; -+ u32 val; -+ -+ ret = eip93_set_ring(mtk, cdr); -+ if (ret) -+ return ret; -+ -+ ret = eip93_set_ring(mtk, rdr); -+ if (ret) -+ return ret; -+ -+ writel((u32 __force)cdr->base_dma, mtk->base + EIP93_REG_PE_CDR_BASE); -+ writel((u32 __force)rdr->base_dma, mtk->base + EIP93_REG_PE_RDR_BASE); -+ -+ val = FIELD_PREP(EIP93_PE_RING_SIZE, EIP93_RING_NUM - 1); -+ writel(val, mtk->base + EIP93_REG_PE_RING_CONFIG); -+ -+ atomic_set(&mtk->ring->free, EIP93_RING_NUM - 1); -+ -+ return 0; -+} -+ -+static void eip93_cleanup(struct eip93_device *mtk) -+{ -+ tasklet_kill(&mtk->ring->done_task); -+ -+ /* Clear/ack all interrupts before disable all */ -+ eip93_irq_clear(mtk, EIP93_INT_ALL); -+ eip93_irq_disable(mtk, EIP93_INT_ALL); -+ -+ writel(0, mtk->base + EIP93_REG_PE_CLOCK_CTRL); -+ -+ eip93_desc_free(mtk); -+ -+ idr_destroy(&mtk->ring->crypto_async_idr); -+} -+ -+static int eip93_crypto_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct eip93_device *mtk; -+ u32 ver, algo_flags; -+ int ret; -+ -+ mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL); -+ if (!mtk) -+ return -ENOMEM; -+ -+ mtk->dev = dev; -+ platform_set_drvdata(pdev, mtk); -+ -+ mtk->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(mtk->base)) -+ return PTR_ERR(mtk->base); -+ -+ mtk->irq = platform_get_irq(pdev, 0); -+ if (mtk->irq < 0) -+ return mtk->irq; -+ -+ ret = devm_request_threaded_irq(mtk->dev, mtk->irq, eip93_irq_handler, -+ NULL, IRQF_ONESHOT, -+ dev_name(mtk->dev), mtk); -+ -+ mtk->ring = devm_kcalloc(mtk->dev, 1, sizeof(*mtk->ring), GFP_KERNEL); -+ if (!mtk->ring) -+ return -ENOMEM; -+ -+ ret = eip93_desc_init(mtk); -+ -+ if (ret) -+ return ret; -+ -+ tasklet_init(&mtk->ring->done_task, eip93_done_task, (unsigned long)mtk); -+ -+ spin_lock_init(&mtk->ring->read_lock); -+ spin_lock_init(&mtk->ring->write_lock); -+ -+ spin_lock_init(&mtk->ring->idr_lock); -+ idr_init(&mtk->ring->crypto_async_idr); -+ -+ algo_flags = readl(mtk->base + EIP93_REG_PE_OPTION_1); -+ -+ eip93_initialize(mtk, algo_flags); -+ -+ /* Init finished, enable RDR interrupt */ -+ eip93_irq_enable(mtk, EIP93_INT_RDR_THRESH); -+ -+ ret = eip93_register_algs(mtk, algo_flags); -+ if (ret) { -+ eip93_cleanup(mtk); -+ return ret; -+ } -+ -+ ver = readl(mtk->base + EIP93_REG_PE_REVISION); -+ /* EIP_EIP_NO:MAJOR_HW_REV:MINOR_HW_REV:HW_PATCH,PE(ALGO_FLAGS) */ -+ dev_info(mtk->dev, "EIP%lu:%lx:%lx:%lx,PE(0x%x:0x%x)\n", -+ FIELD_GET(EIP93_PE_REVISION_EIP_NO, ver), -+ FIELD_GET(EIP93_PE_REVISION_MAJ_HW_REV, ver), -+ FIELD_GET(EIP93_PE_REVISION_MIN_HW_REV, ver), -+ FIELD_GET(EIP93_PE_REVISION_HW_PATCH, ver), -+ algo_flags, -+ readl(mtk->base + EIP93_REG_PE_OPTION_0)); -+ -+ return 0; -+} -+ -+static void eip93_crypto_remove(struct platform_device *pdev) -+{ -+ struct eip93_device *mtk = platform_get_drvdata(pdev); -+ -+ eip93_unregister_algs(ARRAY_SIZE(eip93_algs)); -+ eip93_cleanup(mtk); -+} -+ -+static const struct of_device_id eip93_crypto_of_match[] = { -+ { .compatible = "inside-secure,safexcel-eip93i", }, -+ { .compatible = "inside-secure,safexcel-eip93ie", }, -+ { .compatible = "inside-secure,safexcel-eip93is", }, -+ { .compatible = "inside-secure,safexcel-eip93ies", }, -+ /* IW not supported currently, missing AES-XCB-MAC/AES-CCM */ -+ /* { .compatible = "inside-secure,safexcel-eip93iw", }, */ -+ {} -+}; -+MODULE_DEVICE_TABLE(of, eip93_crypto_of_match); -+ -+static struct platform_driver eip93_crypto_driver = { -+ .probe = eip93_crypto_probe, -+ .remove_new = eip93_crypto_remove, -+ .driver = { -+ .name = "mtk-eip93", -+ .of_match_table = eip93_crypto_of_match, -+ }, -+}; -+module_platform_driver(eip93_crypto_driver); -+ -+MODULE_AUTHOR("Richard van Schagen "); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Mediatek EIP-93 crypto engine driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-main.h -@@ -0,0 +1,155 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -+#include -+#include -+#include -+#include -+#include -+ -+#include "eip93-regs.h" -+ -+#define EIP93_RING_BUSY_DELAY 500 -+ -+#define EIP93_RING_NUM 512 -+#define EIP93_RING_BUSY 32 -+#define EIP93_CRA_PRIORITY 1500 -+ -+#define EIP93_RING_SA_STATE_ADDR(base, idx) ((base) + (idx)) -+#define EIP93_RING_SA_STATE_DMA(dma_base, idx) ((u32 __force)(dma_base) + \ -+ ((idx) * sizeof(struct sa_state))) -+ -+/* cipher algorithms */ -+#define EIP93_ALG_DES BIT(0) -+#define EIP93_ALG_3DES BIT(1) -+#define EIP93_ALG_AES BIT(2) -+#define EIP93_ALG_MASK GENMASK(2, 0) -+/* hash and hmac algorithms */ -+#define EIP93_HASH_MD5 BIT(3) -+#define EIP93_HASH_SHA1 BIT(4) -+#define EIP93_HASH_SHA224 BIT(5) -+#define EIP93_HASH_SHA256 BIT(6) -+#define EIP93_HASH_HMAC BIT(7) -+#define EIP93_HASH_MASK GENMASK(6, 3) -+/* cipher modes */ -+#define EIP93_MODE_CBC BIT(8) -+#define EIP93_MODE_ECB BIT(9) -+#define EIP93_MODE_CTR BIT(10) -+#define EIP93_MODE_RFC3686 BIT(11) -+#define EIP93_MODE_MASK GENMASK(10, 8) -+ -+/* cipher encryption/decryption operations */ -+#define EIP93_ENCRYPT BIT(12) -+#define EIP93_DECRYPT BIT(13) -+ -+#define EIP93_BUSY BIT(14) -+ -+/* descriptor flags */ -+#define EIP93_DESC_DMA_IV BIT(0) -+#define EIP93_DESC_IPSEC BIT(1) -+#define EIP93_DESC_FINISH BIT(2) -+#define EIP93_DESC_LAST BIT(3) -+#define EIP93_DESC_FAKE_HMAC BIT(4) -+#define EIP93_DESC_PRNG BIT(5) -+#define EIP93_DESC_HASH BIT(6) -+#define EIP93_DESC_AEAD BIT(7) -+#define EIP93_DESC_SKCIPHER BIT(8) -+#define EIP93_DESC_ASYNC BIT(9) -+ -+#define IS_DMA_IV(desc_flags) ((desc_flags) & EIP93_DESC_DMA_IV) -+ -+#define IS_DES(flags) ((flags) & EIP93_ALG_DES) -+#define IS_3DES(flags) ((flags) & EIP93_ALG_3DES) -+#define IS_AES(flags) ((flags) & EIP93_ALG_AES) -+ -+#define IS_HASH_MD5(flags) ((flags) & EIP93_HASH_MD5) -+#define IS_HASH_SHA1(flags) ((flags) & EIP93_HASH_SHA1) -+#define IS_HASH_SHA224(flags) ((flags) & EIP93_HASH_SHA224) -+#define IS_HASH_SHA256(flags) ((flags) & EIP93_HASH_SHA256) -+#define IS_HMAC(flags) ((flags) & EIP93_HASH_HMAC) -+ -+#define IS_CBC(mode) ((mode) & EIP93_MODE_CBC) -+#define IS_ECB(mode) ((mode) & EIP93_MODE_ECB) -+#define IS_CTR(mode) ((mode) & EIP93_MODE_CTR) -+#define IS_RFC3686(mode) ((mode) & EIP93_MODE_RFC3686) -+ -+#define IS_BUSY(flags) ((flags) & EIP93_BUSY) -+ -+#define IS_ENCRYPT(dir) ((dir) & EIP93_ENCRYPT) -+#define IS_DECRYPT(dir) ((dir) & EIP93_DECRYPT) -+ -+#define IS_CIPHER(flags) ((flags) & (EIP93_ALG_DES | \ -+ EIP93_ALG_3DES | \ -+ EIP93_ALG_AES)) -+ -+#define IS_HASH(flags) ((flags) & (EIP93_HASH_MD5 | \ -+ EIP93_HASH_SHA1 | \ -+ EIP93_HASH_SHA224 | \ -+ EIP93_HASH_SHA256)) -+ -+/** -+ * struct eip93_device - crypto engine device structure -+ */ -+struct eip93_device { -+ void __iomem *base; -+ struct device *dev; -+ struct clk *clk; -+ int irq; -+ struct eip93_ring *ring; -+}; -+ -+struct eip93_desc_ring { -+ void *base; -+ void *base_end; -+ dma_addr_t base_dma; -+ /* write and read pointers */ -+ void *read; -+ void *write; -+ /* descriptor element offset */ -+ u32 offset; -+}; -+ -+struct eip93_state_pool { -+ void *base; -+ dma_addr_t base_dma; -+}; -+ -+struct eip93_ring { -+ struct tasklet_struct done_task; -+ /* command/result rings */ -+ struct eip93_desc_ring cdr; -+ struct eip93_desc_ring rdr; -+ spinlock_t write_lock; -+ spinlock_t read_lock; -+ atomic_t free; -+ /* aync idr */ -+ spinlock_t idr_lock; -+ struct idr crypto_async_idr; -+}; -+ -+enum eip93_alg_type { -+ EIP93_ALG_TYPE_AEAD, -+ EIP93_ALG_TYPE_SKCIPHER, -+ EIP93_ALG_TYPE_HASH, -+}; -+ -+struct eip93_alg_template { -+ struct eip93_device *mtk; -+ enum eip93_alg_type type; -+ u32 flags; -+ union { -+ struct aead_alg aead; -+ struct skcipher_alg skcipher; -+ struct ahash_alg ahash; -+ } alg; -+}; -+ -+#endif /* _EIP93_MAIN_H_ */ ---- /dev/null -+++ b/drivers/crypto/inside-secure/eip93/eip93-regs.h -@@ -0,0 +1,335 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2019 - 2021 -+ * -+ * Richard van Schagen -+ * Christian Marangi -Date: Tue, 10 Mar 2026 16:16:03 +0100 -Subject: [PATCH] pinctrl: airoha: permit GPIO43-46 for PHY LED0 - -On some board it was found that also the GPIO pin range from 43 to 46 can be -used for PHY LED0. Add these additional GPIO pins to the function groups. - -Signed-off-by: Christian Marangi ---- - drivers/pinctrl/mediatek/pinctrl-airoha.c | 48 +++++++++++++++++++++-- - 1 file changed, 44 insertions(+), 4 deletions(-) - ---- a/drivers/pinctrl/mediatek/pinctrl-airoha.c -+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c -@@ -904,13 +904,21 @@ static const char *const pwm_groups[] = - "gpio44", "gpio45", - "gpio46", "gpio47" }; - static const char *const phy1_led0_groups[] = { "gpio33", "gpio34", -- "gpio35", "gpio42" }; -+ "gpio35", "gpio42", -+ "gpio43", "gpio44", -+ "gpio45", "gpio46" }; - static const char *const phy2_led0_groups[] = { "gpio33", "gpio34", -- "gpio35", "gpio42" }; -+ "gpio35", "gpio42", -+ "gpio43", "gpio44", -+ "gpio45", "gpio46" }; - static const char *const phy3_led0_groups[] = { "gpio33", "gpio34", -- "gpio35", "gpio42" }; -+ "gpio35", "gpio42", -+ "gpio43", "gpio44", -+ "gpio45", "gpio46" }; - static const char *const phy4_led0_groups[] = { "gpio33", "gpio34", -- "gpio35", "gpio42" }; -+ "gpio35", "gpio42", -+ "gpio43", "gpio44", -+ "gpio45", "gpio46" }; - static const char *const phy1_led1_groups[] = { "gpio43", "gpio44", - "gpio45", "gpio46" }; - static const char *const phy2_led1_groups[] = { "gpio43", "gpio44", -@@ -1548,6 +1556,14 @@ static const struct airoha_pinctrl_func_ - LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), - AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, - LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio43", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio44", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio45", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)), -+ AIROHA_PINCTRL_PHY_LED0("gpio46", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)), - }; - - static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = { -@@ -1559,6 +1575,14 @@ static const struct airoha_pinctrl_func_ - LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), - AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, - LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio43", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio44", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio45", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)), -+ AIROHA_PINCTRL_PHY_LED0("gpio46", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)), - }; - - static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = { -@@ -1570,6 +1594,14 @@ static const struct airoha_pinctrl_func_ - LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), - AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, - LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio43", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio44", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio45", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)), -+ AIROHA_PINCTRL_PHY_LED0("gpio46", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)), - }; - - static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = { -@@ -1581,6 +1613,14 @@ static const struct airoha_pinctrl_func_ - LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)), - AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK, - LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio43", GPIO_LAN0_LED0_MODE_MASK, -+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio44", GPIO_LAN1_LED0_MODE_MASK, -+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio45", GPIO_LAN2_LED0_MODE_MASK, -+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)), -+ AIROHA_PINCTRL_PHY_LED0("gpio46", GPIO_LAN3_LED0_MODE_MASK, -+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)), - }; - - static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = { diff --git a/target/linux/airoha/patches-6.12/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch b/target/linux/airoha/patches-6.12/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch deleted file mode 100644 index 3fa8d6d5909..00000000000 --- a/target/linux/airoha/patches-6.12/220-04-dt-bindings-soc-Add-bindings-for-Airoha-SCU-Serdes-l.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 39537b6b334dfac001aba395229adb9318627463 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 28 Oct 2025 12:09:57 +0100 -Subject: [PATCH 04/10] dt-bindings: soc: Add bindings for Airoha SCU Serdes - lines - -The Airoha AN7581 SoC have can configure the SCU serdes lines for -multiple purpose. For example the Serdes for the USB1 port can be both -used for USB 3.0 operation or for Ethernet. Or the USB2 serdes can both -used for USB 3.0 operation or for PCIe. - -Add bindings to permit correct reference of the different ports in DT, -mostly to differenciate the different supported modes internally to the -drivers. - -Signed-off-by: Christian Marangi ---- - include/dt-bindings/soc/airoha,scu-ssr.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - create mode 100644 include/dt-bindings/soc/airoha,scu-ssr.h - ---- /dev/null -+++ b/include/dt-bindings/soc/airoha,scu-ssr.h -@@ -0,0 +1,11 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ -+ -+#ifndef __DT_BINDINGS_AIROHA_SCU_SSR_H -+#define __DT_BINDINGS_AIROHA_SCU_SSR_H -+ -+#define AIROHA_SCU_SERDES_WIFI1 0 -+#define AIROHA_SCU_SERDES_WIFI2 1 -+#define AIROHA_SCU_SERDES_USB1 2 -+#define AIROHA_SCU_SERDES_USB2 3 -+ -+#endif /* __DT_BINDINGS_AIROHA_SCU_SSR_H */ diff --git a/target/linux/airoha/patches-6.12/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch b/target/linux/airoha/patches-6.12/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch deleted file mode 100644 index 1937a692eed..00000000000 --- a/target/linux/airoha/patches-6.12/220-05-dt-bindings-phy-Add-documentation-for-Airoha-AN7581-.patch +++ /dev/null @@ -1,141 +0,0 @@ -From e0095e21dd9179250c304d6df2643e9a50d48edb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Feb 2025 13:25:28 +0100 -Subject: [PATCH 05/10] dt-bindings: phy: Add documentation for Airoha AN7581 - USB PHY - -Add documentation for Airoha AN7581 USB PHY that describe the USB PHY -for the USB controller. - -Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is -always supported. The USB 3.0 mode is optional and depends on the Serdes -mode currently configured on the system for the USB port. - -If the airoha,serdes-port property is not declared, it's assumed USB 3.0 -mode is not supported, as the Serdes mode can't be validated. - -Signed-off-by: Christian Marangi ---- - .../bindings/phy/airoha,an7581-usb-phy.yaml | 83 +++++++++++++++++++ - MAINTAINERS | 7 ++ - .../dt-bindings/phy/airoha,an7581-usb-phy.h | 11 +++ - 3 files changed, 101 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml - create mode 100644 include/dt-bindings/phy/airoha,an7581-usb-phy.h - ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml -@@ -0,0 +1,83 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/phy/airoha,an7581-usb-phy.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Airoha AN7581 SoC USB PHY -+ -+maintainers: -+ - Christian Marangi -+ -+description: > -+ The Airoha AN7581 SoC USB PHY describes the USB PHY for the USB controller. -+ -+ Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is -+ always supported. The USB 3.0 mode is optional and depends on the Serdes -+ mode currently configured on the system for the USB port. -+ -+ If the airoha,serdes-port property is not declared, it's assumed USB 3.0 -+ mode is not supported, as the Serdes mode can't be validated. -+ -+properties: -+ compatible: -+ const: airoha,an7581-usb-phy -+ -+ reg: -+ maxItems: 1 -+ -+ -+ airoha,usb2-monitor-clk-sel: -+ description: Describe what oscillator across the available 4 -+ should be selected for USB 2.0 Slew Rate calibration. -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ enum: [0, 1, 2, 3] -+ -+ airoha,serdes-port: -+ description: Describe what Serdes Port is attached to the USB 3.0 port. -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ enum: [0, 1, 2, 3] -+ -+ airoha,scu: -+ description: Phandle to the SCU node for USB 3.0 Serdes mode validation. -+ $ref: /schemas/types.yaml#/definitions/phandle -+ -+ '#phy-cells': -+ const: 1 -+ -+required: -+ - compatible -+ - reg -+ - airoha,usb2-monitor-clk-sel -+ - '#phy-cells' -+ -+dependentRequired: -+ airoha,serdes-port: [ 'airoha,scu' ] -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ #include -+ -+ phy@1fac0000 { -+ compatible = "airoha,an7581-usb-phy"; -+ reg = <0x1fac0000 0x10000>; -+ -+ airoha,usb2-monitor-clk-sel = ; -+ airoha,scu = <&scu>; -+ airoha,serdes-port = ; -+ -+ #phy-cells = <1>; -+ }; -+ -+ phy@1fae0000 { -+ compatible = "airoha,an7581-usb-phy"; -+ reg = <0x1fae0000 0x10000>; -+ -+ airoha,usb2-monitor-clk-sel = ; -+ -+ #phy-cells = <1>; -+ }; -+ ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -751,6 +751,13 @@ S: Maintained - F: Documentation/devicetree/bindings/spi/airoha,en7581-snand.yaml - F: drivers/spi/spi-airoha-snfi.c - -+AIROHA USB PHY DRIVER -+M: Christian Marangi -+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -+S: Maintained -+F: Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml -+F: include/dt-bindings/phy/airoha,an7581-usb-phy.h -+ - AIRSPY MEDIA DRIVER - L: linux-media@vger.kernel.org - S: Orphan ---- /dev/null -+++ b/include/dt-bindings/phy/airoha,an7581-usb-phy.h -@@ -0,0 +1,11 @@ -+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ -+ -+#ifndef _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ -+#define _DT_BINDINGS_AIROHA_AN7581_USB_PHY_H_ -+ -+#define AIROHA_USB2_MONCLK_SEL0 0 -+#define AIROHA_USB2_MONCLK_SEL1 1 -+#define AIROHA_USB2_MONCLK_SEL2 2 -+#define AIROHA_USB2_MONCLK_SEL3 3 -+ -+#endif diff --git a/target/linux/airoha/patches-6.12/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch b/target/linux/airoha/patches-6.12/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch deleted file mode 100644 index e61de0441e3..00000000000 --- a/target/linux/airoha/patches-6.12/220-06-phy-move-Airoha-PCIe-PHY-driver-to-dedicated-directo.patch +++ /dev/null @@ -1,1885 +0,0 @@ -From 1bfe1cc581ffba2462580496507497840aa018aa Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Mar 2025 15:23:50 +0100 -Subject: [PATCH 06/10] phy: move Airoha PCIe PHY driver to dedicated directory - -To keep the generic PHY directory tidy, move the PCIe PHY driver to a -dedicated directory. - -This is also in preparation for support of the Airoha USB PHY driver. - -Signed-off-by: Christian Marangi ---- - MAINTAINERS | 4 +- - drivers/phy/Kconfig | 11 +- - drivers/phy/Makefile | 5 +- - drivers/phy/airoha/Kconfig | 13 + - drivers/phy/airoha/Makefile | 3 + - drivers/phy/airoha/phy-airoha-pcie-regs.h | 494 ++++++++ - drivers/phy/airoha/phy-airoha-pcie.c | 1290 +++++++++++++++++++++ - 7 files changed, 1806 insertions(+), 14 deletions(-) - create mode 100644 drivers/phy/airoha/Kconfig - create mode 100644 drivers/phy/airoha/Makefile - create mode 100644 drivers/phy/airoha/phy-airoha-pcie-regs.h - create mode 100644 drivers/phy/airoha/phy-airoha-pcie.c - -# diff --git a/MAINTAINERS b/MAINTAINERS -# index 2468f4fea5b7..3f930a613658 100644 -# --- a/MAINTAINERS -# +++ b/MAINTAINERS -# @@ -733,8 +733,8 @@ M: Lorenzo Bianconi -# L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -# S: Maintained -# F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml -# -F: drivers/phy/phy-airoha-pcie-regs.h -# -F: drivers/phy/phy-airoha-pcie.c -# +F: drivers/phy/airoha/phy-airoha-pcie-regs.h -# +F: drivers/phy/airoha/phy-airoha-pcie.c - -# AIROHA SPI SNFI DRIVER -# M: Lorenzo Bianconi ---- a/drivers/phy/Kconfig -+++ b/drivers/phy/Kconfig -@@ -72,16 +72,7 @@ config PHY_CAN_TRANSCEIVER - functional modes using gpios and sets the attribute max link - rate, for CAN drivers. - --config PHY_AIROHA_PCIE -- tristate "Airoha PCIe-PHY Driver" -- depends on ARCH_AIROHA || COMPILE_TEST -- depends on OF -- select GENERIC_PHY -- help -- Say Y here to add support for Airoha PCIe PHY driver. -- This driver create the basic PHY instance and provides initialize -- callback for PCIe GEN3 port. -- -+source "drivers/phy/airoha/Kconfig" - source "drivers/phy/allwinner/Kconfig" - source "drivers/phy/amlogic/Kconfig" - source "drivers/phy/broadcom/Kconfig" ---- a/drivers/phy/Makefile -+++ b/drivers/phy/Makefile -@@ -10,8 +10,8 @@ obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy - obj-$(CONFIG_PHY_XGENE) += phy-xgene.o - obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o - obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o --obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o --obj-y += allwinner/ \ -+obj-y += airoha/ \ -+ allwinner/ \ - amlogic/ \ - broadcom/ \ - cadence/ \ ---- /dev/null -+++ b/drivers/phy/airoha/Kconfig -@@ -0,0 +1,13 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+# -+# Phy drivers for Airoha devices -+# -+config PHY_AIROHA_PCIE -+ tristate "Airoha PCIe-PHY Driver" -+ depends on ARCH_AIROHA || COMPILE_TEST -+ depends on OF -+ select GENERIC_PHY -+ help -+ Say Y here to add support for Airoha PCIe PHY driver. -+ This driver create the basic PHY instance and provides initialize -+ callback for PCIe GEN3 port. ---- /dev/null -+++ b/drivers/phy/airoha/Makefile -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o ---- /dev/null -+++ b/drivers/phy/airoha/phy-airoha-pcie-regs.h -@@ -0,0 +1,494 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#ifndef _PHY_AIROHA_PCIE_H -+#define _PHY_AIROHA_PCIE_H -+ -+/* CSR_2L */ -+#define REG_CSR_2L_CMN 0x0000 -+#define CSR_2L_PXP_CMN_LANE_EN BIT(0) -+#define CSR_2L_PXP_CMN_TRIM_MASK GENMASK(28, 24) -+ -+#define REG_CSR_2L_JCPLL_IB_EXT 0x0004 -+#define REG_CSR_2L_JCPLL_LPF_SHCK_EN BIT(8) -+#define CSR_2L_PXP_JCPLL_CHP_IBIAS GENMASK(21, 16) -+#define CSR_2L_PXP_JCPLL_CHP_IOFST GENMASK(29, 24) -+ -+#define REG_CSR_2L_JCPLL_LPF_BR 0x0008 -+#define CSR_2L_PXP_JCPLL_LPF_BR GENMASK(4, 0) -+#define CSR_2L_PXP_JCPLL_LPF_BC GENMASK(12, 8) -+#define CSR_2L_PXP_JCPLL_LPF_BP GENMASK(20, 16) -+#define CSR_2L_PXP_JCPLL_LPF_BWR GENMASK(28, 24) -+ -+#define REG_CSR_2L_JCPLL_LPF_BWC 0x000c -+#define CSR_2L_PXP_JCPLL_LPF_BWC GENMASK(4, 0) -+#define CSR_2L_PXP_JCPLL_KBAND_CODE GENMASK(23, 16) -+#define CSR_2L_PXP_JCPLL_KBAND_DIV GENMASK(26, 24) -+ -+#define REG_CSR_2L_JCPLL_KBAND_KFC 0x0010 -+#define CSR_2L_PXP_JCPLL_KBAND_KFC GENMASK(1, 0) -+#define CSR_2L_PXP_JCPLL_KBAND_KF GENMASK(9, 8) -+#define CSR_2L_PXP_JCPLL_KBAND_KS GENMASK(17, 16) -+#define CSR_2L_PXP_JCPLL_POSTDIV_EN BIT(24) -+ -+#define REG_CSR_2L_JCPLL_MMD_PREDIV_MODE 0x0014 -+#define CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) -+#define CSR_2L_PXP_JCPLL_POSTDIV_D2 BIT(16) -+#define CSR_2L_PXP_JCPLL_POSTDIV_D5 BIT(24) -+ -+#define CSR_2L_PXP_JCPLL_MONCK 0x0018 -+#define CSR_2L_PXP_JCPLL_REFIN_DIV GENMASK(25, 24) -+ -+#define REG_CSR_2L_JCPLL_RST_DLY 0x001c -+#define CSR_2L_PXP_JCPLL_RST_DLY GENMASK(2, 0) -+#define CSR_2L_PXP_JCPLL_RST BIT(8) -+#define CSR_2L_PXP_JCPLL_SDM_DI_EN BIT(16) -+#define CSR_2L_PXP_JCPLL_SDM_DI_LS GENMASK(25, 24) -+ -+#define REG_CSR_2L_JCPLL_SDM_IFM 0x0020 -+#define CSR_2L_PXP_JCPLL_SDM_IFM BIT(0) -+ -+#define REG_CSR_2L_JCPLL_SDM_HREN 0x0024 -+#define CSR_2L_PXP_JCPLL_SDM_HREN BIT(0) -+#define CSR_2L_PXP_JCPLL_TCL_AMP_EN BIT(8) -+#define CSR_2L_PXP_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) -+#define CSR_2L_PXP_JCPLL_TCL_AMP_VREF GENMASK(28, 24) -+ -+#define REG_CSR_2L_JCPLL_TCL_CMP 0x0028 -+#define CSR_2L_PXP_JCPLL_TCL_LPF_EN BIT(16) -+#define CSR_2L_PXP_JCPLL_TCL_LPF_BW GENMASK(26, 24) -+ -+#define REG_CSR_2L_JCPLL_VCODIV 0x002c -+#define CSR_2L_PXP_JCPLL_VCO_CFIX GENMASK(9, 8) -+#define CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN BIT(16) -+#define CSR_2L_PXP_JCPLL_VCO_SCAPWR GENMASK(26, 24) -+ -+#define REG_CSR_2L_JCPLL_VCO_TCLVAR 0x0030 -+#define CSR_2L_PXP_JCPLL_VCO_TCLVAR GENMASK(2, 0) -+ -+#define REG_CSR_2L_JCPLL_SSC 0x0038 -+#define CSR_2L_PXP_JCPLL_SSC_EN BIT(0) -+#define CSR_2L_PXP_JCPLL_SSC_PHASE_INI BIT(8) -+#define CSR_2L_PXP_JCPLL_SSC_TRI_EN BIT(16) -+ -+#define REG_CSR_2L_JCPLL_SSC_DELTA1 0x003c -+#define CSR_2L_PXP_JCPLL_SSC_DELTA1 GENMASK(15, 0) -+#define CSR_2L_PXP_JCPLL_SSC_DELTA GENMASK(31, 16) -+ -+#define REG_CSR_2L_JCPLL_SSC_PERIOD 0x0040 -+#define CSR_2L_PXP_JCPLL_SSC_PERIOD GENMASK(15, 0) -+ -+#define REG_CSR_2L_JCPLL_TCL_VTP_EN 0x004c -+#define CSR_2L_PXP_JCPLL_SPARE_LOW GENMASK(31, 24) -+ -+#define REG_CSR_2L_JCPLL_TCL_KBAND_VREF 0x0050 -+#define CSR_2L_PXP_JCPLL_TCL_KBAND_VREF GENMASK(4, 0) -+#define CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN BIT(24) -+ -+#define REG_CSR_2L_750M_SYS_CK 0x0054 -+#define CSR_2L_PXP_TXPLL_LPF_SHCK_EN BIT(16) -+#define CSR_2L_PXP_TXPLL_CHP_IBIAS GENMASK(29, 24) -+ -+#define REG_CSR_2L_TXPLL_CHP_IOFST 0x0058 -+#define CSR_2L_PXP_TXPLL_CHP_IOFST GENMASK(5, 0) -+#define CSR_2L_PXP_TXPLL_LPF_BR GENMASK(12, 8) -+#define CSR_2L_PXP_TXPLL_LPF_BC GENMASK(20, 16) -+#define CSR_2L_PXP_TXPLL_LPF_BP GENMASK(28, 24) -+ -+#define REG_CSR_2L_TXPLL_LPF_BWR 0x005c -+#define CSR_2L_PXP_TXPLL_LPF_BWR GENMASK(4, 0) -+#define CSR_2L_PXP_TXPLL_LPF_BWC GENMASK(12, 8) -+#define CSR_2L_PXP_TXPLL_KBAND_CODE GENMASK(31, 24) -+ -+#define REG_CSR_2L_TXPLL_KBAND_DIV 0x0060 -+#define CSR_2L_PXP_TXPLL_KBAND_DIV GENMASK(2, 0) -+#define CSR_2L_PXP_TXPLL_KBAND_KFC GENMASK(9, 8) -+#define CSR_2L_PXP_TXPLL_KBAND_KF GENMASK(17, 16) -+#define CSR_2L_PXP_txpll_KBAND_KS GENMASK(25, 24) -+ -+#define REG_CSR_2L_TXPLL_POSTDIV 0x0064 -+#define CSR_2L_PXP_TXPLL_POSTDIV_EN BIT(0) -+#define CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE GENMASK(9, 8) -+#define CSR_2L_PXP_TXPLL_PHY_CK1_EN BIT(24) -+ -+#define REG_CSR_2L_TXPLL_PHY_CK2 0x0068 -+#define CSR_2L_PXP_TXPLL_REFIN_INTERNAL BIT(24) -+ -+#define REG_CSR_2L_TXPLL_REFIN_DIV 0x006c -+#define CSR_2L_PXP_TXPLL_REFIN_DIV GENMASK(1, 0) -+#define CSR_2L_PXP_TXPLL_RST_DLY GENMASK(10, 8) -+#define CSR_2L_PXP_TXPLL_PLL_RSTB BIT(16) -+ -+#define REG_CSR_2L_TXPLL_SDM_DI_LS 0x0070 -+#define CSR_2L_PXP_TXPLL_SDM_DI_LS GENMASK(1, 0) -+#define CSR_2L_PXP_TXPLL_SDM_IFM BIT(8) -+#define CSR_2L_PXP_TXPLL_SDM_ORD GENMASK(25, 24) -+ -+#define REG_CSR_2L_TXPLL_SDM_OUT 0x0074 -+#define CSR_2L_PXP_TXPLL_TCL_AMP_EN BIT(16) -+#define CSR_2L_PXP_TXPLL_TCL_AMP_GAIN GENMASK(26, 24) -+ -+#define REG_CSR_2L_TXPLL_TCL_AMP_VREF 0x0078 -+#define CSR_2L_PXP_TXPLL_TCL_AMP_VREF GENMASK(4, 0) -+#define CSR_2L_PXP_TXPLL_TCL_LPF_EN BIT(24) -+ -+#define REG_CSR_2L_TXPLL_TCL_LPF_BW 0x007c -+#define CSR_2L_PXP_TXPLL_TCL_LPF_BW GENMASK(2, 0) -+#define CSR_2L_PXP_TXPLL_VCO_CFIX GENMASK(17, 16) -+#define CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN BIT(24) -+ -+#define REG_CSR_2L_TXPLL_VCO_SCAPWR 0x0080 -+#define CSR_2L_PXP_TXPLL_VCO_SCAPWR GENMASK(2, 0) -+ -+#define REG_CSR_2L_TXPLL_SSC 0x0084 -+#define CSR_2L_PXP_TXPLL_SSC_EN BIT(0) -+#define CSR_2L_PXP_TXPLL_SSC_PHASE_INI BIT(8) -+ -+#define REG_CSR_2L_TXPLL_SSC_DELTA1 0x0088 -+#define CSR_2L_PXP_TXPLL_SSC_DELTA1 GENMASK(15, 0) -+#define CSR_2L_PXP_TXPLL_SSC_DELTA GENMASK(31, 16) -+ -+#define REG_CSR_2L_TXPLL_SSC_PERIOD 0x008c -+#define CSR_2L_PXP_txpll_SSC_PERIOD GENMASK(15, 0) -+ -+#define REG_CSR_2L_TXPLL_VTP 0x0090 -+#define CSR_2L_PXP_TXPLL_VTP_EN BIT(0) -+ -+#define REG_CSR_2L_TXPLL_TCL_VTP 0x0098 -+#define CSR_2L_PXP_TXPLL_SPARE_L GENMASK(31, 24) -+ -+#define REG_CSR_2L_TXPLL_TCL_KBAND_VREF 0x009c -+#define CSR_2L_PXP_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) -+#define CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN BIT(24) -+ -+#define REG_CSR_2L_TXPLL_POSTDIV_D256 0x00a0 -+#define CSR_2L_PXP_CLKTX0_AMP GENMASK(10, 8) -+#define CSR_2L_PXP_CLKTX0_OFFSET GENMASK(17, 16) -+#define CSR_2L_PXP_CLKTX0_SR GENMASK(25, 24) -+ -+#define REG_CSR_2L_CLKTX0_FORCE_OUT1 0x00a4 -+#define CSR_2L_PXP_CLKTX0_HZ BIT(8) -+#define CSR_2L_PXP_CLKTX0_IMP_SEL GENMASK(20, 16) -+#define CSR_2L_PXP_CLKTX1_AMP GENMASK(26, 24) -+ -+#define REG_CSR_2L_CLKTX1_OFFSET 0x00a8 -+#define CSR_2L_PXP_CLKTX1_OFFSET GENMASK(1, 0) -+#define CSR_2L_PXP_CLKTX1_SR GENMASK(9, 8) -+#define CSR_2L_PXP_CLKTX1_HZ BIT(24) -+ -+#define REG_CSR_2L_CLKTX1_IMP_SEL 0x00ac -+#define CSR_2L_PXP_CLKTX1_IMP_SEL GENMASK(4, 0) -+ -+#define REG_CSR_2L_PLL_CMN_RESERVE0 0x00b0 -+#define CSR_2L_PXP_PLL_RESERVE_MASK GENMASK(15, 0) -+ -+#define REG_CSR_2L_TX0_CKLDO 0x00cc -+#define CSR_2L_PXP_TX0_CKLDO_EN BIT(0) -+#define CSR_2L_PXP_TX0_DMEDGEGEN_EN BIT(24) -+ -+#define REG_CSR_2L_TX1_CKLDO 0x00e8 -+#define CSR_2L_PXP_TX1_CKLDO_EN BIT(0) -+#define CSR_2L_PXP_TX1_DMEDGEGEN_EN BIT(24) -+ -+#define REG_CSR_2L_TX1_MULTLANE 0x00ec -+#define CSR_2L_PXP_TX1_MULTLANE_EN BIT(0) -+ -+#define REG_CSR_2L_RX0_REV0 0x00fc -+#define CSR_2L_PXP_VOS_PNINV GENMASK(19, 18) -+#define CSR_2L_PXP_FE_GAIN_NORMAL_MODE GENMASK(22, 20) -+#define CSR_2L_PXP_FE_GAIN_TRAIN_MODE GENMASK(26, 24) -+ -+#define REG_CSR_2L_RX0_PHYCK_DIV 0x0100 -+#define CSR_2L_PXP_RX0_PHYCK_SEL GENMASK(9, 8) -+#define CSR_2L_PXP_RX0_PHYCK_RSTB BIT(16) -+#define CSR_2L_PXP_RX0_TDC_CK_SEL BIT(24) -+ -+#define REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV 0x0104 -+#define CSR_2L_PXP_CDR0_PD_EDGE_DISABLE BIT(8) -+ -+#define REG_CSR_2L_CDR0_LPF_RATIO 0x0110 -+#define CSR_2L_PXP_CDR0_LPF_TOP_LIM GENMASK(26, 8) -+ -+#define REG_CSR_2L_CDR0_PR_INJ_MODE 0x011c -+#define CSR_2L_PXP_CDR0_INJ_FORCE_OFF BIT(24) -+ -+#define REG_CSR_2L_CDR0_PR_BETA_DAC 0x0120 -+#define CSR_2L_PXP_CDR0_PR_BETA_SEL GENMASK(19, 16) -+#define CSR_2L_PXP_CDR0_PR_KBAND_DIV GENMASK(26, 24) -+ -+#define REG_CSR_2L_CDR0_PR_VREG_IBAND 0x0124 -+#define CSR_2L_PXP_CDR0_PR_VREG_IBAND GENMASK(2, 0) -+#define CSR_2L_PXP_CDR0_PR_VREG_CKBUF GENMASK(10, 8) -+ -+#define REG_CSR_2L_CDR0_PR_CKREF_DIV 0x0128 -+#define CSR_2L_PXP_CDR0_PR_CKREF_DIV GENMASK(1, 0) -+ -+#define REG_CSR_2L_CDR0_PR_MONCK 0x012c -+#define CSR_2L_PXP_CDR0_PR_MONCK_ENABLE BIT(0) -+#define CSR_2L_PXP_CDR0_PR_RESERVE0 GENMASK(19, 16) -+ -+#define REG_CSR_2L_CDR0_PR_COR_HBW 0x0130 -+#define CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON BIT(8) -+#define CSR_2L_PXP_CDR0_PR_CKREF_DIV1 GENMASK(17, 16) -+ -+#define REG_CSR_2L_CDR0_PR_MONPI 0x0134 -+#define CSR_2L_PXP_CDR0_PR_XFICK_EN BIT(8) -+ -+#define REG_CSR_2L_RX0_SIGDET_DCTEST 0x0140 -+#define CSR_2L_PXP_RX0_SIGDET_LPF_CTRL GENMASK(9, 8) -+#define CSR_2L_PXP_RX0_SIGDET_PEAK GENMASK(25, 24) -+ -+#define REG_CSR_2L_RX0_SIGDET_VTH_SEL 0x0144 -+#define CSR_2L_PXP_RX0_SIGDET_VTH_SEL GENMASK(4, 0) -+#define CSR_2L_PXP_RX0_FE_VB_EQ1_EN BIT(24) -+ -+#define REG_CSR_2L_PXP_RX0_FE_VB_EQ2 0x0148 -+#define CSR_2L_PXP_RX0_FE_VB_EQ2_EN BIT(0) -+#define CSR_2L_PXP_RX0_FE_VB_EQ3_EN BIT(8) -+#define CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB BIT(16) -+ -+#define REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS 0x0158 -+#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS GENMASK(29, 24) -+ -+#define REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS 0x015c -+#define CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS GENMASK(5, 0) -+#define CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS GENMASK(13, 8) -+ -+#define REG_CSR_2L_RX1_REV0 0x01b4 -+ -+#define REG_CSR_2L_RX1_PHYCK_DIV 0x01b8 -+#define CSR_2L_PXP_RX1_PHYCK_SEL GENMASK(9, 8) -+#define CSR_2L_PXP_RX1_PHYCK_RSTB BIT(16) -+#define CSR_2L_PXP_RX1_TDC_CK_SEL BIT(24) -+ -+#define REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV 0x01bc -+#define CSR_2L_PXP_CDR1_PD_EDGE_DISABLE BIT(8) -+ -+#define REG_CSR_2L_CDR1_PR_BETA_DAC 0x01d8 -+#define CSR_2L_PXP_CDR1_PR_BETA_SEL GENMASK(19, 16) -+#define CSR_2L_PXP_CDR1_PR_KBAND_DIV GENMASK(26, 24) -+ -+#define REG_CSR_2L_CDR1_PR_MONCK 0x01e4 -+#define CSR_2L_PXP_CDR1_PR_MONCK_ENABLE BIT(0) -+#define CSR_2L_PXP_CDR1_PR_RESERVE0 GENMASK(19, 16) -+ -+#define REG_CSR_2L_CDR1_LPF_RATIO 0x01c8 -+#define CSR_2L_PXP_CDR1_LPF_TOP_LIM GENMASK(26, 8) -+ -+#define REG_CSR_2L_CDR1_PR_INJ_MODE 0x01d4 -+#define CSR_2L_PXP_CDR1_INJ_FORCE_OFF BIT(24) -+ -+#define REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL 0x01dc -+#define CSR_2L_PXP_CDR1_PR_VREG_IBAND GENMASK(2, 0) -+#define CSR_2L_PXP_CDR1_PR_VREG_CKBUF GENMASK(10, 8) -+ -+#define REG_CSR_2L_CDR1_PR_CKREF_DIV 0x01e0 -+#define CSR_2L_PXP_CDR1_PR_CKREF_DIV GENMASK(1, 0) -+ -+#define REG_CSR_2L_CDR1_PR_COR_HBW 0x01e8 -+#define CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON BIT(8) -+#define CSR_2L_PXP_CDR1_PR_CKREF_DIV1 GENMASK(17, 16) -+ -+#define REG_CSR_2L_CDR1_PR_MONPI 0x01ec -+#define CSR_2L_PXP_CDR1_PR_XFICK_EN BIT(8) -+ -+#define REG_CSR_2L_RX1_DAC_RANGE_EYE 0x01f4 -+#define CSR_2L_PXP_RX1_SIGDET_LPF_CTRL GENMASK(25, 24) -+ -+#define REG_CSR_2L_RX1_SIGDET_NOVTH 0x01f8 -+#define CSR_2L_PXP_RX1_SIGDET_PEAK GENMASK(9, 8) -+#define CSR_2L_PXP_RX1_SIGDET_VTH_SEL GENMASK(20, 16) -+ -+#define REG_CSR_2L_RX1_FE_VB_EQ1 0x0200 -+#define CSR_2L_PXP_RX1_FE_VB_EQ1_EN BIT(0) -+#define CSR_2L_PXP_RX1_FE_VB_EQ2_EN BIT(8) -+#define CSR_2L_PXP_RX1_FE_VB_EQ3_EN BIT(16) -+#define CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB BIT(24) -+ -+#define REG_CSR_2L_RX1_OSCAL_VGA1IOS 0x0214 -+#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS GENMASK(5, 0) -+#define CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS GENMASK(13, 8) -+#define CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS GENMASK(21, 16) -+ -+/* PMA */ -+#define REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1 0x0004 -+#define PCIE_LCPLL_MAN_PWDB BIT(0) -+ -+#define REG_PCIE_PMA_SEQUENCE_DISB_CTRL1 0x010c -+#define PCIE_DISB_RX_SDCAL_EN BIT(0) -+ -+#define REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1 0x0114 -+#define PCIE_FORCE_RX_SDCAL_EN BIT(0) -+ -+#define REG_PCIE_PMA_SS_RX_FREQ_DET1 0x014c -+#define PCIE_PLL_FT_LOCK_CYCLECNT GENMASK(15, 0) -+#define PCIE_PLL_FT_UNLOCK_CYCLECNT GENMASK(31, 16) -+ -+#define REG_PCIE_PMA_SS_RX_FREQ_DET2 0x0150 -+#define PCIE_LOCK_TARGET_BEG GENMASK(15, 0) -+#define PCIE_LOCK_TARGET_END GENMASK(31, 16) -+ -+#define REG_PCIE_PMA_SS_RX_FREQ_DET3 0x0154 -+#define PCIE_UNLOCK_TARGET_BEG GENMASK(15, 0) -+#define PCIE_UNLOCK_TARGET_END GENMASK(31, 16) -+ -+#define REG_PCIE_PMA_SS_RX_FREQ_DET4 0x0158 -+#define PCIE_FREQLOCK_DET_EN GENMASK(2, 0) -+#define PCIE_LOCK_LOCKTH GENMASK(11, 8) -+#define PCIE_UNLOCK_LOCKTH GENMASK(15, 12) -+ -+#define REG_PCIE_PMA_SS_RX_CAL1 0x0160 -+#define REG_PCIE_PMA_SS_RX_CAL2 0x0164 -+#define PCIE_CAL_OUT_OS GENMASK(11, 8) -+ -+#define REG_PCIE_PMA_SS_RX_SIGDET0 0x0168 -+#define PCIE_SIGDET_WIN_NONVLD_TIMES GENMASK(28, 24) -+ -+#define REG_PCIE_PMA_TX_RESET 0x0260 -+#define PCIE_TX_TOP_RST BIT(0) -+#define PCIE_TX_CAL_RST BIT(8) -+ -+#define REG_PCIE_PMA_RX_FORCE_MODE0 0x0294 -+#define PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL GENMASK(1, 0) -+ -+#define REG_PCIE_PMA_SS_DA_XPON_PWDB0 0x034c -+#define PCIE_DA_XPON_CDR_PR_PWDB BIT(8) -+ -+#define REG_PCIE_PMA_SW_RESET 0x0460 -+#define PCIE_SW_RX_FIFO_RST BIT(0) -+#define PCIE_SW_RX_RST BIT(1) -+#define PCIE_SW_TX_RST BIT(2) -+#define PCIE_SW_PMA_RST BIT(3) -+#define PCIE_SW_ALLPCS_RST BIT(4) -+#define PCIE_SW_REF_RST BIT(5) -+#define PCIE_SW_TX_FIFO_RST BIT(6) -+#define PCIE_SW_XFI_TXPCS_RST BIT(7) -+#define PCIE_SW_XFI_RXPCS_RST BIT(8) -+#define PCIE_SW_XFI_RXPCS_BIST_RST BIT(9) -+#define PCIE_SW_HSG_TXPCS_RST BIT(10) -+#define PCIE_SW_HSG_RXPCS_RST BIT(11) -+#define PCIE_PMA_SW_RST (PCIE_SW_RX_FIFO_RST | \ -+ PCIE_SW_RX_RST | \ -+ PCIE_SW_TX_RST | \ -+ PCIE_SW_PMA_RST | \ -+ PCIE_SW_ALLPCS_RST | \ -+ PCIE_SW_REF_RST | \ -+ PCIE_SW_TX_FIFO_RST | \ -+ PCIE_SW_XFI_TXPCS_RST | \ -+ PCIE_SW_XFI_RXPCS_RST | \ -+ PCIE_SW_XFI_RXPCS_BIST_RST | \ -+ PCIE_SW_HSG_TXPCS_RST | \ -+ PCIE_SW_HSG_RXPCS_RST) -+ -+#define REG_PCIE_PMA_RO_RX_FREQDET 0x0530 -+#define PCIE_RO_FBCK_LOCK BIT(0) -+#define PCIE_RO_FL_OUT GENMASK(31, 16) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC 0x0794 -+#define PCIE_FORCE_DA_PXP_CDR_PR_IDAC GENMASK(10, 0) -+#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC BIT(16) -+#define PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW BIT(24) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW 0x0798 -+#define PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW GENMASK(30, 0) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS 0x079c -+#define PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW BIT(16) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW 0x0800 -+#define PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW GENMASK(30, 0) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB 0x081c -+#define PCIE_FORCE_DA_PXP_CDR_PD_PWDB BIT(0) -+#define PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB BIT(8) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C 0x0820 -+#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN BIT(0) -+#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN BIT(8) -+#define PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN BIT(16) -+#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN BIT(24) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB 0x0824 -+#define PCIE_FORCE_DA_PXP_CDR_PR_PWDB BIT(16) -+#define PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB BIT(24) -+ -+#define REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT 0x0828 -+#define PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN BIT(0) -+#define PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN BIT(8) -+#define PCIE_FORCE_DA_PXP_JCPLL_EN BIT(16) -+#define PCIE_FORCE_SEL_DA_PXP_JCPLL_EN BIT(24) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST 0x0084c -+#define PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB BIT(16) -+#define PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB BIT(24) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT 0x0854 -+#define PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN BIT(0) -+#define PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN BIT(8) -+#define PCIE_FORCE_DA_PXP_TXPLL_EN BIT(16) -+#define PCIE_FORCE_SEL_DA_PXP_TXPLL_EN BIT(24) -+ -+#define REG_PCIE_PMA_SCAN_MODE 0x0884 -+#define PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(0) -+#define PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN BIT(8) -+ -+#define REG_PCIE_PMA_DIG_RESERVE_13 0x08bc -+#define PCIE_FLL_IDAC_PCIEG1 GENMASK(10, 0) -+#define PCIE_FLL_IDAC_PCIEG2 GENMASK(26, 16) -+ -+#define REG_PCIE_PMA_DIG_RESERVE_14 0x08c0 -+#define PCIE_FLL_IDAC_PCIEG3 GENMASK(10, 0) -+#define PCIE_FLL_LOAD_EN BIT(16) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL 0x088c -+#define PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL GENMASK(1, 0) -+#define PCIE_FORCE_SEL_DA_PXP_RX_FE_GAIN_CTRL BIT(8) -+ -+#define REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB 0x0894 -+#define PCIE_FORCE_DA_PXP_RX_FE_PWDB BIT(0) -+#define PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB BIT(8) -+ -+#define REG_PCIE_PMA_DIG_RESERVE_12 0x08b8 -+#define PCIE_FORCE_PMA_RX_SPEED GENMASK(7, 4) -+#define PCIE_FORCE_SEL_PMA_RX_SPEED BIT(7) -+ -+#define REG_PCIE_PMA_DIG_RESERVE_17 0x08e0 -+ -+#define REG_PCIE_PMA_DIG_RESERVE_18 0x08e4 -+#define PCIE_PXP_RX_VTH_SEL_PCIE_G1 GENMASK(4, 0) -+#define PCIE_PXP_RX_VTH_SEL_PCIE_G2 GENMASK(12, 8) -+#define PCIE_PXP_RX_VTH_SEL_PCIE_G3 GENMASK(20, 16) -+ -+#define REG_PCIE_PMA_DIG_RESERVE_19 0x08e8 -+#define PCIE_PCP_RX_REV0_PCIE_GEN1 GENMASK(31, 16) -+ -+#define REG_PCIE_PMA_DIG_RESERVE_20 0x08ec -+#define PCIE_PCP_RX_REV0_PCIE_GEN2 GENMASK(15, 0) -+#define PCIE_PCP_RX_REV0_PCIE_GEN3 GENMASK(31, 16) -+ -+#define REG_PCIE_PMA_DIG_RESERVE_21 0x08f0 -+#define REG_PCIE_PMA_DIG_RESERVE_22 0x08f4 -+#define REG_PCIE_PMA_DIG_RESERVE_27 0x0908 -+#define REG_PCIE_PMA_DIG_RESERVE_30 0x0914 -+ -+/* DTIME */ -+#define REG_PCIE_PEXTP_DIG_GLB44 0x00 -+#define PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL GENMASK(7, 0) -+#define PCIE_XTP_RXDET_EN_STB_T_SEL GENMASK(15, 8) -+#define PCIE_XTP_RXDET_FINISH_STB_T_SEL GENMASK(23, 16) -+#define PCIE_XTP_TXPD_TX_DATA_EN_DLY GENMASK(27, 24) -+#define PCIE_XTP_TXPD_RXDET_DONE_CDT BIT(28) -+#define PCIE_XTP_RXDET_LATCH_STB_T_SEL GENMASK(31, 29) -+ -+/* RX AEQ */ -+#define REG_PCIE_PEXTP_DIG_LN_RX30_P0 0x0000 -+#define PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT GENMASK(7, 0) -+#define PCIE_XTP_LN_RX_PDOWN_T2RLB_DIG_EN BIT(8) -+#define PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT GENMASK(31, 16) -+ -+#define REG_PCIE_PEXTP_DIG_LN_RX30_P1 0x0100 -+ -+#endif /* _PHY_AIROHA_PCIE_H */ ---- /dev/null -+++ b/drivers/phy/airoha/phy-airoha-pcie.c -@@ -0,0 +1,1290 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Lorenzo Bianconi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "phy-airoha-pcie-regs.h" -+ -+#define LEQ_LEN_CTRL_MAX_VAL 7 -+#define FREQ_LOCK_MAX_ATTEMPT 10 -+ -+/* PCIe-PHY initialization time in ms needed by the hw to complete */ -+#define PHY_HW_INIT_TIME_MS 30 -+ -+enum airoha_pcie_port_gen { -+ PCIE_PORT_GEN1 = 1, -+ PCIE_PORT_GEN2, -+ PCIE_PORT_GEN3, -+}; -+ -+/** -+ * struct airoha_pcie_phy - PCIe phy driver main structure -+ * @dev: pointer to device -+ * @phy: pointer to generic phy -+ * @csr_2l: Analogic lane IO mapped register base address -+ * @pma0: IO mapped register base address of PMA0-PCIe -+ * @pma1: IO mapped register base address of PMA1-PCIe -+ * @p0_xr_dtime: IO mapped register base address of port0 Tx-Rx detection time -+ * @p1_xr_dtime: IO mapped register base address of port1 Tx-Rx detection time -+ * @rx_aeq: IO mapped register base address of Rx AEQ training -+ */ -+struct airoha_pcie_phy { -+ struct device *dev; -+ struct phy *phy; -+ void __iomem *csr_2l; -+ void __iomem *pma0; -+ void __iomem *pma1; -+ void __iomem *p0_xr_dtime; -+ void __iomem *p1_xr_dtime; -+ void __iomem *rx_aeq; -+}; -+ -+static void airoha_phy_clear_bits(void __iomem *reg, u32 mask) -+{ -+ u32 val = readl(reg) & ~mask; -+ -+ writel(val, reg); -+} -+ -+static void airoha_phy_set_bits(void __iomem *reg, u32 mask) -+{ -+ u32 val = readl(reg) | mask; -+ -+ writel(val, reg); -+} -+ -+static void airoha_phy_update_bits(void __iomem *reg, u32 mask, u32 val) -+{ -+ u32 tmp = readl(reg); -+ -+ tmp &= ~mask; -+ tmp |= val & mask; -+ writel(tmp, reg); -+} -+ -+#define airoha_phy_update_field(reg, mask, val) \ -+ do { \ -+ BUILD_BUG_ON_MSG(!__builtin_constant_p((mask)), \ -+ "mask is not constant"); \ -+ airoha_phy_update_bits((reg), (mask), \ -+ FIELD_PREP((mask), (val))); \ -+ } while (0) -+ -+#define airoha_phy_csr_2l_clear_bits(pcie_phy, reg, mask) \ -+ airoha_phy_clear_bits((pcie_phy)->csr_2l + (reg), (mask)) -+#define airoha_phy_csr_2l_set_bits(pcie_phy, reg, mask) \ -+ airoha_phy_set_bits((pcie_phy)->csr_2l + (reg), (mask)) -+#define airoha_phy_csr_2l_update_field(pcie_phy, reg, mask, val) \ -+ airoha_phy_update_field((pcie_phy)->csr_2l + (reg), (mask), (val)) -+#define airoha_phy_pma0_clear_bits(pcie_phy, reg, mask) \ -+ airoha_phy_clear_bits((pcie_phy)->pma0 + (reg), (mask)) -+#define airoha_phy_pma1_clear_bits(pcie_phy, reg, mask) \ -+ airoha_phy_clear_bits((pcie_phy)->pma1 + (reg), (mask)) -+#define airoha_phy_pma0_set_bits(pcie_phy, reg, mask) \ -+ airoha_phy_set_bits((pcie_phy)->pma0 + (reg), (mask)) -+#define airoha_phy_pma1_set_bits(pcie_phy, reg, mask) \ -+ airoha_phy_set_bits((pcie_phy)->pma1 + (reg), (mask)) -+#define airoha_phy_pma0_update_field(pcie_phy, reg, mask, val) \ -+ airoha_phy_update_field((pcie_phy)->pma0 + (reg), (mask), (val)) -+#define airoha_phy_pma1_update_field(pcie_phy, reg, mask, val) \ -+ airoha_phy_update_field((pcie_phy)->pma1 + (reg), (mask), (val)) -+ -+static void -+airoha_phy_init_lane0_rx_fw_pre_calib(struct airoha_pcie_phy *pcie_phy, -+ enum airoha_pcie_port_gen gen) -+{ -+ u32 fl_out_target = gen == PCIE_PORT_GEN3 ? 41600 : 41941; -+ u32 lock_cyclecnt = gen == PCIE_PORT_GEN3 ? 26000 : 32767; -+ u32 pr_idac, val, cdr_pr_idac_tmp = 0; -+ int i; -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1, -+ PCIE_LCPLL_MAN_PWDB); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, -+ PCIE_LOCK_TARGET_BEG, -+ fl_out_target - 100); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, -+ PCIE_LOCK_TARGET_END, -+ fl_out_target + 100); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, -+ PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_LOCK_LOCKTH, 0x3); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, -+ PCIE_UNLOCK_TARGET_BEG, -+ fl_out_target - 100); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, -+ PCIE_UNLOCK_TARGET_END, -+ fl_out_target + 100); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, -+ PCIE_PLL_FT_UNLOCK_CYCLECNT, -+ lock_cyclecnt); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_UNLOCK_LOCKTH, 0x3); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, -+ CSR_2L_PXP_CDR0_INJ_FORCE_OFF); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); -+ -+ for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN, 0x3); -+ -+ usleep_range(10000, 15000); -+ -+ val = FIELD_GET(PCIE_RO_FL_OUT, -+ readl(pcie_phy->pma0 + -+ REG_PCIE_PMA_RO_RX_FREQDET)); -+ if (val > fl_out_target) -+ cdr_pr_idac_tmp = i << 8; -+ } -+ -+ for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { -+ pr_idac = cdr_pr_idac_tmp | (0x1 << i); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN, 0x3); -+ -+ usleep_range(10000, 15000); -+ -+ val = FIELD_GET(PCIE_RO_FL_OUT, -+ readl(pcie_phy->pma0 + -+ REG_PCIE_PMA_RO_RX_FREQDET)); -+ if (val < fl_out_target) -+ pr_idac &= ~(0x1 << i); -+ -+ cdr_pr_idac_tmp = pr_idac; -+ } -+ -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, -+ cdr_pr_idac_tmp); -+ -+ for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { -+ u32 val; -+ -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN, 0x3); -+ -+ usleep_range(10000, 15000); -+ -+ val = readl(pcie_phy->pma0 + REG_PCIE_PMA_RO_RX_FREQDET); -+ if (val & PCIE_RO_FBCK_LOCK) -+ break; -+ } -+ -+ /* turn off force mode and update band values */ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_INJ_MODE, -+ CSR_2L_PXP_CDR0_INJ_FORCE_OFF); -+ -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); -+ if (gen == PCIE_PORT_GEN3) { -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_DIG_RESERVE_14, -+ PCIE_FLL_IDAC_PCIEG3, -+ cdr_pr_idac_tmp); -+ } else { -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_DIG_RESERVE_13, -+ PCIE_FLL_IDAC_PCIEG1, -+ cdr_pr_idac_tmp); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_DIG_RESERVE_13, -+ PCIE_FLL_IDAC_PCIEG2, -+ cdr_pr_idac_tmp); -+ } -+} -+ -+static void -+airoha_phy_init_lane1_rx_fw_pre_calib(struct airoha_pcie_phy *pcie_phy, -+ enum airoha_pcie_port_gen gen) -+{ -+ u32 fl_out_target = gen == PCIE_PORT_GEN3 ? 41600 : 41941; -+ u32 lock_cyclecnt = gen == PCIE_PORT_GEN3 ? 26000 : 32767; -+ u32 pr_idac, val, cdr_pr_idac_tmp = 0; -+ int i; -+ -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_SS_LCPLL_PWCTL_SETTING_1, -+ PCIE_LCPLL_MAN_PWDB); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, -+ PCIE_LOCK_TARGET_BEG, -+ fl_out_target - 100); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET2, -+ PCIE_LOCK_TARGET_END, -+ fl_out_target + 100); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, -+ PCIE_PLL_FT_LOCK_CYCLECNT, lock_cyclecnt); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_LOCK_LOCKTH, 0x3); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, -+ PCIE_UNLOCK_TARGET_BEG, -+ fl_out_target - 100); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET3, -+ PCIE_UNLOCK_TARGET_END, -+ fl_out_target + 100); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET1, -+ PCIE_PLL_FT_UNLOCK_CYCLECNT, -+ lock_cyclecnt); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_UNLOCK_LOCKTH, 0x3); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, -+ CSR_2L_PXP_CDR1_INJ_FORCE_OFF); -+ -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_DA_PXP_CDR_PR_LPF_R_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_DA_PXP_CDR_PR_LPF_C_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_DA_PXP_CDR_PR_PWDB); -+ -+ for (i = 0; i < LEQ_LEN_CTRL_MAX_VAL; i++) { -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, i << 8); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN, 0x3); -+ -+ usleep_range(10000, 15000); -+ -+ val = FIELD_GET(PCIE_RO_FL_OUT, -+ readl(pcie_phy->pma1 + -+ REG_PCIE_PMA_RO_RX_FREQDET)); -+ if (val > fl_out_target) -+ cdr_pr_idac_tmp = i << 8; -+ } -+ -+ for (i = LEQ_LEN_CTRL_MAX_VAL; i >= 0; i--) { -+ pr_idac = cdr_pr_idac_tmp | (0x1 << i); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, pr_idac); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN, 0x3); -+ -+ usleep_range(10000, 15000); -+ -+ val = FIELD_GET(PCIE_RO_FL_OUT, -+ readl(pcie_phy->pma1 + -+ REG_PCIE_PMA_RO_RX_FREQDET)); -+ if (val < fl_out_target) -+ pr_idac &= ~(0x1 << i); -+ -+ cdr_pr_idac_tmp = pr_idac; -+ } -+ -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_DA_PXP_CDR_PR_IDAC, -+ cdr_pr_idac_tmp); -+ -+ for (i = 0; i < FREQ_LOCK_MAX_ATTEMPT; i++) { -+ u32 val; -+ -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_SS_RX_FREQ_DET4, -+ PCIE_FREQLOCK_DET_EN, 0x3); -+ -+ usleep_range(10000, 15000); -+ -+ val = readl(pcie_phy->pma1 + REG_PCIE_PMA_RO_RX_FREQDET); -+ if (val & PCIE_RO_FBCK_LOCK) -+ break; -+ } -+ -+ /* turn off force mode and update band values */ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_INJ_MODE, -+ CSR_2L_PXP_CDR1_INJ_FORCE_OFF); -+ -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_R_EN); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_LPF_C, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_LPF_C_EN); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_PIEYE_PWDB, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_PWDB); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_CDR_PR_IDAC); -+ if (gen == PCIE_PORT_GEN3) { -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_DIG_RESERVE_14, -+ PCIE_FLL_IDAC_PCIEG3, -+ cdr_pr_idac_tmp); -+ } else { -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_DIG_RESERVE_13, -+ PCIE_FLL_IDAC_PCIEG1, -+ cdr_pr_idac_tmp); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_DIG_RESERVE_13, -+ PCIE_FLL_IDAC_PCIEG2, -+ cdr_pr_idac_tmp); -+ } -+} -+ -+static void airoha_pcie_phy_init_default(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CMN, -+ CSR_2L_PXP_CMN_TRIM_MASK, 0x10); -+ writel(0xcccbcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_21); -+ writel(0xcccb, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_22); -+ writel(0xcccbcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_21); -+ writel(0xcccb, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_22); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CMN, -+ CSR_2L_PXP_CMN_LANE_EN); -+} -+ -+static void airoha_pcie_phy_init_clk_out(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_TXPLL_POSTDIV_D256, -+ CSR_2L_PXP_CLKTX0_AMP, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_CLKTX0_FORCE_OUT1, -+ CSR_2L_PXP_CLKTX1_AMP, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_TXPLL_POSTDIV_D256, -+ CSR_2L_PXP_CLKTX0_OFFSET, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, -+ CSR_2L_PXP_CLKTX1_OFFSET, 0x2); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX0_FORCE_OUT1, -+ CSR_2L_PXP_CLKTX0_HZ); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, -+ CSR_2L_PXP_CLKTX1_HZ); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_CLKTX0_FORCE_OUT1, -+ CSR_2L_PXP_CLKTX0_IMP_SEL, 0x12); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CLKTX1_IMP_SEL, -+ CSR_2L_PXP_CLKTX1_IMP_SEL, 0x12); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV_D256, -+ CSR_2L_PXP_CLKTX0_SR); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CLKTX1_OFFSET, -+ CSR_2L_PXP_CLKTX1_SR); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_PLL_CMN_RESERVE0, -+ CSR_2L_PXP_PLL_RESERVE_MASK, 0xd0d); -+} -+ -+static void airoha_pcie_phy_init_csr_2l(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, -+ PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | -+ PCIE_SW_RX_RST); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, -+ PCIE_SW_XFI_RXPCS_RST | PCIE_SW_REF_RST | -+ PCIE_SW_RX_RST); -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, -+ PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_TX_RESET, -+ PCIE_TX_TOP_RST | PCIE_TX_CAL_RST); -+} -+ -+static void airoha_pcie_phy_init_rx(struct airoha_pcie_phy *pcie_phy) -+{ -+ writel(0x2a00090b, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_17); -+ writel(0x2a00090b, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_17); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONPI, -+ CSR_2L_PXP_CDR0_PR_XFICK_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONPI, -+ CSR_2L_PXP_CDR1_PR_XFICK_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, -+ REG_CSR_2L_CDR0_PD_PICAL_CKD8_INV, -+ CSR_2L_PXP_CDR0_PD_EDGE_DISABLE); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, -+ REG_CSR_2L_CDR1_PD_PICAL_CKD8_INV, -+ CSR_2L_PXP_CDR1_PD_EDGE_DISABLE); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, -+ CSR_2L_PXP_RX0_PHYCK_SEL, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, -+ CSR_2L_PXP_RX1_PHYCK_SEL, 0x1); -+} -+ -+static void airoha_pcie_phy_init_jcpll(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_JCPLL_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_JCPLL_EN); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_VTP_EN, -+ CSR_2L_PXP_JCPLL_SPARE_LOW, 0x20); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, -+ CSR_2L_PXP_JCPLL_RST); -+ writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_JCPLL_SSC_DELTA1); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, -+ CSR_2L_PXP_JCPLL_SSC_PERIOD); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, -+ CSR_2L_PXP_JCPLL_SSC_PHASE_INI); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, -+ CSR_2L_PXP_JCPLL_SSC_TRI_EN); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, -+ CSR_2L_PXP_JCPLL_LPF_BR, 0xa); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, -+ CSR_2L_PXP_JCPLL_LPF_BP, 0xc); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, -+ CSR_2L_PXP_JCPLL_LPF_BC, 0x1f); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, -+ CSR_2L_PXP_JCPLL_LPF_BWC, 0x1e); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BR, -+ CSR_2L_PXP_JCPLL_LPF_BWR, 0xa); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, -+ CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, -+ 0x1); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, CSR_2L_PXP_JCPLL_MONCK, -+ CSR_2L_PXP_JCPLL_REFIN_DIV); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_VOS, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_SDM_PCW); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, -+ PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, -+ 0x50000000); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_JCPLL_SDM_PCW, -+ PCIE_FORCE_DA_PXP_JCPLL_SDM_PCW, -+ 0x50000000); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, -+ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, -+ CSR_2L_PXP_JCPLL_POSTDIV_D5); -+ airoha_phy_csr_2l_set_bits(pcie_phy, -+ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, -+ CSR_2L_PXP_JCPLL_POSTDIV_D2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, -+ CSR_2L_PXP_JCPLL_RST_DLY, 0x4); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, -+ CSR_2L_PXP_JCPLL_SDM_DI_LS); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_KBAND_VREF, -+ CSR_2L_PXP_JCPLL_VCO_KBAND_MEAS_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, -+ CSR_2L_PXP_JCPLL_CHP_IOFST); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, -+ CSR_2L_PXP_JCPLL_CHP_IBIAS, 0xc); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_JCPLL_MMD_PREDIV_MODE, -+ CSR_2L_PXP_JCPLL_MMD_PREDIV_MODE, -+ 0x1); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, -+ CSR_2L_PXP_JCPLL_VCO_HALFLSB_EN); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, -+ CSR_2L_PXP_JCPLL_VCO_CFIX, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCODIV, -+ CSR_2L_PXP_JCPLL_VCO_SCAPWR, 0x4); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_IB_EXT, -+ REG_CSR_2L_JCPLL_LPF_SHCK_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, -+ CSR_2L_PXP_JCPLL_POSTDIV_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, -+ CSR_2L_PXP_JCPLL_KBAND_KFC); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, -+ CSR_2L_PXP_JCPLL_KBAND_KF, 0x3); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_KBAND_KFC, -+ CSR_2L_PXP_JCPLL_KBAND_KS); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, -+ CSR_2L_PXP_JCPLL_KBAND_DIV, 0x1); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_KBAND_LOAD_EN); -+ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SCAN_MODE, -+ PCIE_FORCE_DA_PXP_JCPLL_KBAND_LOAD_EN); -+ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_LPF_BWC, -+ CSR_2L_PXP_JCPLL_KBAND_CODE, 0xe4); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, -+ CSR_2L_PXP_JCPLL_TCL_AMP_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, -+ CSR_2L_PXP_JCPLL_TCL_LPF_EN); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_JCPLL_TCL_KBAND_VREF, -+ CSR_2L_PXP_JCPLL_TCL_KBAND_VREF, 0xf); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, -+ CSR_2L_PXP_JCPLL_TCL_AMP_GAIN, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, -+ CSR_2L_PXP_JCPLL_TCL_AMP_VREF, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_TCL_CMP, -+ CSR_2L_PXP_JCPLL_TCL_LPF_BW, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_VCO_TCLVAR, -+ CSR_2L_PXP_JCPLL_VCO_TCLVAR, 0x3); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_CKOUT_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_JCPLL_CKOUT_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_JCPLL_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_JCPLL_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_PXP_JCPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_JCPLL_EN); -+} -+ -+static void airoha_pcie_phy_txpll(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_TXPLL_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_TXPLL_EN); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, -+ CSR_2L_PXP_TXPLL_PLL_RSTB); -+ writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC_PERIOD, -+ CSR_2L_PXP_txpll_SSC_PERIOD); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, -+ CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, -+ CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, -+ CSR_2L_PXP_TXPLL_REFIN_DIV); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, -+ CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, -+ PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, -+ 0xc800000); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_SDM_PCW, -+ PCIE_FORCE_DA_PXP_TXPLL_SDM_PCW, -+ 0xc800000); -+ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, -+ CSR_2L_PXP_TXPLL_SDM_IFM); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, -+ CSR_2L_PXP_TXPLL_SSC_PHASE_INI); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, -+ CSR_2L_PXP_TXPLL_RST_DLY, 0x4); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, -+ CSR_2L_PXP_TXPLL_SDM_DI_LS); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_DI_LS, -+ CSR_2L_PXP_TXPLL_SDM_ORD, 0x3); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, -+ CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); -+ writel(0x0, pcie_phy->csr_2l + REG_CSR_2L_TXPLL_SSC_DELTA1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, -+ CSR_2L_PXP_TXPLL_LPF_BP, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, -+ CSR_2L_PXP_TXPLL_LPF_BC, 0x18); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, -+ CSR_2L_PXP_TXPLL_LPF_BR, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_CHP_IOFST, -+ CSR_2L_PXP_TXPLL_CHP_IOFST, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_750M_SYS_CK, -+ CSR_2L_PXP_TXPLL_CHP_IBIAS, 0x2d); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_VTP, -+ CSR_2L_PXP_TXPLL_SPARE_L, 0x1); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, -+ CSR_2L_PXP_TXPLL_LPF_BWC); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, -+ CSR_2L_PXP_TXPLL_MMD_PREDIV_MODE); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_REFIN_DIV, -+ CSR_2L_PXP_TXPLL_REFIN_DIV); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, -+ CSR_2L_PXP_TXPLL_VCO_HALFLSB_EN); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_VCO_SCAPWR, -+ CSR_2L_PXP_TXPLL_VCO_SCAPWR, 0x7); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, -+ CSR_2L_PXP_TXPLL_VCO_CFIX, 0x3); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PR_IDAC, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_SDM_PCW); -+ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, -+ CSR_2L_PXP_TXPLL_SSC_PHASE_INI); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, -+ CSR_2L_PXP_TXPLL_LPF_BWR); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, -+ CSR_2L_PXP_TXPLL_REFIN_INTERNAL); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_KBAND_VREF, -+ CSR_2L_PXP_TXPLL_VCO_KBAND_MEAS_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_VTP, -+ CSR_2L_PXP_TXPLL_VTP_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, -+ CSR_2L_PXP_TXPLL_PHY_CK1_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_PHY_CK2, -+ CSR_2L_PXP_TXPLL_REFIN_INTERNAL); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_SSC, -+ CSR_2L_PXP_TXPLL_SSC_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_750M_SYS_CK, -+ CSR_2L_PXP_TXPLL_LPF_SHCK_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_POSTDIV, -+ CSR_2L_PXP_TXPLL_POSTDIV_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, -+ CSR_2L_PXP_TXPLL_KBAND_KFC); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, -+ CSR_2L_PXP_TXPLL_KBAND_KF, 0x3); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, -+ CSR_2L_PXP_txpll_KBAND_KS, 0x1); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_KBAND_DIV, -+ CSR_2L_PXP_TXPLL_KBAND_DIV, 0x4); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_LPF_BWR, -+ CSR_2L_PXP_TXPLL_KBAND_CODE, 0xe4); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, -+ CSR_2L_PXP_TXPLL_TCL_AMP_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TXPLL_TCL_AMP_VREF, -+ CSR_2L_PXP_TXPLL_TCL_LPF_EN); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_TXPLL_TCL_KBAND_VREF, -+ CSR_2L_PXP_TXPLL_TCL_KBAND_VREF, 0xf); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_SDM_OUT, -+ CSR_2L_PXP_TXPLL_TCL_AMP_GAIN, 0x3); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_TXPLL_TCL_AMP_VREF, -+ CSR_2L_PXP_TXPLL_TCL_AMP_VREF, 0xb); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_TXPLL_TCL_LPF_BW, -+ CSR_2L_PXP_TXPLL_TCL_LPF_BW, 0x3); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_CKOUT_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_TXPLL_CKOUT_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_TXPLL_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_SEL_DA_PXP_TXPLL_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_TXPLL_CKOUT, -+ PCIE_FORCE_DA_PXP_TXPLL_EN); -+} -+ -+static void airoha_pcie_phy_init_ssc_jcpll(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, -+ CSR_2L_PXP_JCPLL_SSC_DELTA1, 0x106); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_DELTA1, -+ CSR_2L_PXP_JCPLL_SSC_DELTA, 0x106); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_JCPLL_SSC_PERIOD, -+ CSR_2L_PXP_JCPLL_SSC_PERIOD, 0x31b); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, -+ CSR_2L_PXP_JCPLL_SSC_PHASE_INI); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, -+ CSR_2L_PXP_JCPLL_SSC_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_IFM, -+ CSR_2L_PXP_JCPLL_SDM_IFM); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SDM_HREN, -+ CSR_2L_PXP_JCPLL_SDM_HREN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_RST_DLY, -+ CSR_2L_PXP_JCPLL_SDM_DI_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, -+ CSR_2L_PXP_JCPLL_SSC_TRI_EN); -+} -+ -+static void -+airoha_pcie_phy_set_rxlan0_signal_detect(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, -+ CSR_2L_PXP_CDR0_PR_LDO_FORCE_ON); -+ -+ usleep_range(100, 200); -+ -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, -+ PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, -+ PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, -+ PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); -+ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, -+ CSR_2L_PXP_RX0_SIGDET_PEAK, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, -+ CSR_2L_PXP_RX0_SIGDET_VTH_SEL, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, -+ CSR_2L_PXP_VOS_PNINV, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_SIGDET_DCTEST, -+ CSR_2L_PXP_RX0_SIGDET_LPF_CTRL, 0x1); -+ -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, -+ PCIE_CAL_OUT_OS, 0x0); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, -+ CSR_2L_PXP_RX0_FE_VCM_GEN_PWDB); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, -+ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); -+ airoha_phy_pma0_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, -+ PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, -+ PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, -+ PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); -+ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, -+ PCIE_DISB_RX_SDCAL_EN); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, -+ PCIE_FORCE_RX_SDCAL_EN); -+ usleep_range(150, 200); -+ airoha_phy_pma0_clear_bits(pcie_phy, -+ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, -+ PCIE_FORCE_RX_SDCAL_EN); -+} -+ -+static void -+airoha_pcie_phy_set_rxlan1_signal_detect(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, -+ CSR_2L_PXP_CDR1_PR_LDO_FORCE_ON); -+ -+ usleep_range(100, 200); -+ -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_19, -+ PCIE_PCP_RX_REV0_PCIE_GEN1, 0x18b0); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, -+ PCIE_PCP_RX_REV0_PCIE_GEN2, 0x18b0); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_20, -+ PCIE_PCP_RX_REV0_PCIE_GEN3, 0x1030); -+ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, -+ CSR_2L_PXP_RX1_SIGDET_PEAK, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_SIGDET_NOVTH, -+ CSR_2L_PXP_RX1_SIGDET_VTH_SEL, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, -+ CSR_2L_PXP_VOS_PNINV, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_DAC_RANGE_EYE, -+ CSR_2L_PXP_RX1_SIGDET_LPF_CTRL, 0x1); -+ -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_CAL2, -+ PCIE_CAL_OUT_OS, 0x0); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, -+ CSR_2L_PXP_RX1_FE_VCM_GEN_PWDB); -+ -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, -+ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); -+ airoha_phy_pma1_update_field(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_GAIN_CTRL, -+ PCIE_FORCE_DA_PXP_RX_FE_GAIN_CTRL, 0x3); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_RX_FORCE_MODE0, -+ PCIE_FORCE_DA_XPON_RX_FE_GAIN_CTRL, 0x1); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_SS_RX_SIGDET0, -+ PCIE_SIGDET_WIN_NONVLD_TIMES, 0x3); -+ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SEQUENCE_DISB_CTRL1, -+ PCIE_DISB_RX_SDCAL_EN); -+ -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, -+ PCIE_FORCE_RX_SDCAL_EN); -+ usleep_range(150, 200); -+ airoha_phy_pma1_clear_bits(pcie_phy, -+ REG_PCIE_PMA_CTRL_SEQUENCE_FORCE_CTRL1, -+ PCIE_FORCE_RX_SDCAL_EN); -+} -+ -+static void airoha_pcie_phy_set_rxflow(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, -+ PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | -+ PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_SCAN_RST, -+ PCIE_FORCE_DA_PXP_RX_SIGDET_PWDB | -+ PCIE_FORCE_SEL_DA_PXP_RX_SIGDET_PWDB); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, -+ PCIE_FORCE_DA_PXP_CDR_PD_PWDB | -+ PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); -+ airoha_phy_pma0_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, -+ PCIE_FORCE_DA_PXP_RX_FE_PWDB | -+ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_CDR_PD_PWDB, -+ PCIE_FORCE_DA_PXP_CDR_PD_PWDB | -+ PCIE_FORCE_SEL_DA_PXP_CDR_PD_PWDB); -+ airoha_phy_pma1_set_bits(pcie_phy, -+ REG_PCIE_PMA_FORCE_DA_PXP_RX_FE_PWDB, -+ PCIE_FORCE_DA_PXP_RX_FE_PWDB | -+ PCIE_FORCE_SEL_DA_PXP_RX_FE_PWDB); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_PHYCK_DIV, -+ CSR_2L_PXP_RX0_PHYCK_RSTB | -+ CSR_2L_PXP_RX0_TDC_CK_SEL); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_PHYCK_DIV, -+ CSR_2L_PXP_RX1_PHYCK_RSTB | -+ CSR_2L_PXP_RX1_TDC_CK_SEL); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, -+ PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | -+ PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | -+ PCIE_SW_TX_FIFO_RST); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, -+ PCIE_SW_RX_FIFO_RST | PCIE_SW_TX_RST | -+ PCIE_SW_PMA_RST | PCIE_SW_ALLPCS_RST | -+ PCIE_SW_TX_FIFO_RST); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_PXP_RX0_FE_VB_EQ2, -+ CSR_2L_PXP_RX0_FE_VB_EQ2_EN | -+ CSR_2L_PXP_RX0_FE_VB_EQ3_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX0_SIGDET_VTH_SEL, -+ CSR_2L_PXP_RX0_FE_VB_EQ1_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_RX1_FE_VB_EQ1, -+ CSR_2L_PXP_RX1_FE_VB_EQ1_EN | -+ CSR_2L_PXP_RX1_FE_VB_EQ2_EN | -+ CSR_2L_PXP_RX1_FE_VB_EQ3_EN); -+ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, -+ CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX0_REV0, -+ CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, -+ CSR_2L_PXP_FE_GAIN_NORMAL_MODE, 0x4); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_REV0, -+ CSR_2L_PXP_FE_GAIN_TRAIN_MODE, 0x4); -+} -+ -+static void airoha_pcie_phy_set_pr(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, -+ CSR_2L_PXP_CDR0_PR_VREG_IBAND, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_VREG_IBAND, -+ CSR_2L_PXP_CDR0_PR_VREG_CKBUF, 0x5); -+ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_CKREF_DIV, -+ CSR_2L_PXP_CDR0_PR_CKREF_DIV); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_COR_HBW, -+ CSR_2L_PXP_CDR0_PR_CKREF_DIV1); -+ -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, -+ CSR_2L_PXP_CDR1_PR_VREG_IBAND, 0x5); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_CDR1_PR_VREG_IBAND_VAL, -+ CSR_2L_PXP_CDR1_PR_VREG_CKBUF, 0x5); -+ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_CKREF_DIV, -+ CSR_2L_PXP_CDR1_PR_CKREF_DIV); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_COR_HBW, -+ CSR_2L_PXP_CDR1_PR_CKREF_DIV1); -+ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_LPF_RATIO, -+ CSR_2L_PXP_CDR0_LPF_TOP_LIM, 0x20000); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_LPF_RATIO, -+ CSR_2L_PXP_CDR1_LPF_TOP_LIM, 0x20000); -+ -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, -+ CSR_2L_PXP_CDR0_PR_BETA_SEL, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, -+ CSR_2L_PXP_CDR1_PR_BETA_SEL, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_BETA_DAC, -+ CSR_2L_PXP_CDR0_PR_KBAND_DIV, 0x4); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_BETA_DAC, -+ CSR_2L_PXP_CDR1_PR_KBAND_DIV, 0x4); -+} -+ -+static void airoha_pcie_phy_set_txflow(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, -+ CSR_2L_PXP_TX0_CKLDO_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, -+ CSR_2L_PXP_TX1_CKLDO_EN); -+ -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX0_CKLDO, -+ CSR_2L_PXP_TX0_DMEDGEGEN_EN); -+ airoha_phy_csr_2l_set_bits(pcie_phy, REG_CSR_2L_TX1_CKLDO, -+ CSR_2L_PXP_TX1_DMEDGEGEN_EN); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_TX1_MULTLANE, -+ CSR_2L_PXP_TX1_MULTLANE_EN); -+} -+ -+static void airoha_pcie_phy_set_rx_mode(struct airoha_pcie_phy *pcie_phy) -+{ -+ writel(0x804000, pcie_phy->pma0 + REG_PCIE_PMA_DIG_RESERVE_27); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, -+ PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, -+ PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, -+ PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, -+ 0x77700); -+ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, -+ CSR_2L_PXP_CDR0_PR_MONCK_ENABLE); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR0_PR_MONCK, -+ CSR_2L_PXP_CDR0_PR_RESERVE0, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_PXP_RX0_OSCAL_CTLE1IOS, -+ CSR_2L_PXP_RX0_PR_OSCAL_VGA1IOS, 0x19); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, -+ CSR_2L_PXP_RX0_PR_OSCAL_VGA1VOS, 0x19); -+ airoha_phy_csr_2l_update_field(pcie_phy, -+ REG_CSR_2L_PXP_RX0_OSCA_VGA1VOS, -+ CSR_2L_PXP_RX0_PR_OSCAL_VGA2IOS, 0x14); -+ -+ writel(0x804000, pcie_phy->pma1 + REG_PCIE_PMA_DIG_RESERVE_27); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, -+ PCIE_PXP_RX_VTH_SEL_PCIE_G1, 0x5); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, -+ PCIE_PXP_RX_VTH_SEL_PCIE_G2, 0x5); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_18, -+ PCIE_PXP_RX_VTH_SEL_PCIE_G3, 0x5); -+ -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_30, -+ 0x77700); -+ -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, -+ CSR_2L_PXP_CDR1_PR_MONCK_ENABLE); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_CDR1_PR_MONCK, -+ CSR_2L_PXP_CDR1_PR_RESERVE0, 0x2); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, -+ CSR_2L_PXP_RX1_PR_OSCAL_VGA1IOS, 0x19); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, -+ CSR_2L_PXP_RX1_PR_OSCAL_VGA1VOS, 0x19); -+ airoha_phy_csr_2l_update_field(pcie_phy, REG_CSR_2L_RX1_OSCAL_VGA1IOS, -+ CSR_2L_PXP_RX1_PR_OSCAL_VGA2IOS, 0x14); -+} -+ -+static void airoha_pcie_phy_load_kflow(struct airoha_pcie_phy *pcie_phy) -+{ -+ airoha_phy_pma0_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, -+ PCIE_FORCE_PMA_RX_SPEED, 0xa); -+ airoha_phy_pma1_update_field(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, -+ PCIE_FORCE_PMA_RX_SPEED, 0xa); -+ airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); -+ airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN3); -+ -+ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, -+ PCIE_FORCE_PMA_RX_SPEED); -+ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_12, -+ PCIE_FORCE_PMA_RX_SPEED); -+ usleep_range(100, 200); -+ -+ airoha_phy_init_lane0_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); -+ airoha_phy_init_lane1_rx_fw_pre_calib(pcie_phy, PCIE_PORT_GEN2); -+} -+ -+/** -+ * airoha_pcie_phy_init() - Initialize the phy -+ * @phy: the phy to be initialized -+ * -+ * Initialize the phy registers. -+ * The hardware settings will be reset during suspend, it should be -+ * reinitialized when the consumer calls phy_init() again on resume. -+ */ -+static int airoha_pcie_phy_init(struct phy *phy) -+{ -+ struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); -+ u32 val; -+ -+ /* Setup Tx-Rx detection time */ -+ val = FIELD_PREP(PCIE_XTP_RXDET_VCM_OFF_STB_T_SEL, 0x33) | -+ FIELD_PREP(PCIE_XTP_RXDET_EN_STB_T_SEL, 0x1) | -+ FIELD_PREP(PCIE_XTP_RXDET_FINISH_STB_T_SEL, 0x2) | -+ FIELD_PREP(PCIE_XTP_TXPD_TX_DATA_EN_DLY, 0x3) | -+ FIELD_PREP(PCIE_XTP_RXDET_LATCH_STB_T_SEL, 0x1); -+ writel(val, pcie_phy->p0_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); -+ writel(val, pcie_phy->p1_xr_dtime + REG_PCIE_PEXTP_DIG_GLB44); -+ /* Setup Rx AEQ training time */ -+ val = FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_L1P2_EXIT_WAIT, 0x32) | -+ FIELD_PREP(PCIE_XTP_LN_RX_PDOWN_E0_AEQEN_WAIT, 0x5050); -+ writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P0); -+ writel(val, pcie_phy->rx_aeq + REG_PCIE_PEXTP_DIG_LN_RX30_P1); -+ -+ /* enable load FLL-K flow */ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, -+ PCIE_FLL_LOAD_EN); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_DIG_RESERVE_14, -+ PCIE_FLL_LOAD_EN); -+ -+ airoha_pcie_phy_init_default(pcie_phy); -+ airoha_pcie_phy_init_clk_out(pcie_phy); -+ airoha_pcie_phy_init_csr_2l(pcie_phy); -+ -+ usleep_range(100, 200); -+ -+ airoha_pcie_phy_init_rx(pcie_phy); -+ /* phase 1, no ssc for K TXPLL */ -+ airoha_pcie_phy_init_jcpll(pcie_phy); -+ -+ usleep_range(500, 600); -+ -+ /* TX PLL settings */ -+ airoha_pcie_phy_txpll(pcie_phy); -+ -+ usleep_range(200, 300); -+ -+ /* SSC JCPLL setting */ -+ airoha_pcie_phy_init_ssc_jcpll(pcie_phy); -+ -+ usleep_range(100, 200); -+ -+ /* Rx lan0 signal detect */ -+ airoha_pcie_phy_set_rxlan0_signal_detect(pcie_phy); -+ /* Rx lan1 signal detect */ -+ airoha_pcie_phy_set_rxlan1_signal_detect(pcie_phy); -+ /* RX FLOW */ -+ airoha_pcie_phy_set_rxflow(pcie_phy); -+ -+ usleep_range(100, 200); -+ -+ airoha_pcie_phy_set_pr(pcie_phy); -+ /* TX FLOW */ -+ airoha_pcie_phy_set_txflow(pcie_phy); -+ -+ usleep_range(100, 200); -+ /* RX mode setting */ -+ airoha_pcie_phy_set_rx_mode(pcie_phy); -+ /* Load K-Flow */ -+ airoha_pcie_phy_load_kflow(pcie_phy); -+ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, -+ PCIE_DA_XPON_CDR_PR_PWDB); -+ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, -+ PCIE_DA_XPON_CDR_PR_PWDB); -+ -+ usleep_range(100, 200); -+ -+ airoha_phy_pma0_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, -+ PCIE_DA_XPON_CDR_PR_PWDB); -+ airoha_phy_pma1_set_bits(pcie_phy, REG_PCIE_PMA_SS_DA_XPON_PWDB0, -+ PCIE_DA_XPON_CDR_PR_PWDB); -+ -+ /* Wait for the PCIe PHY to complete initialization before returning */ -+ msleep(PHY_HW_INIT_TIME_MS); -+ -+ return 0; -+} -+ -+static int airoha_pcie_phy_exit(struct phy *phy) -+{ -+ struct airoha_pcie_phy *pcie_phy = phy_get_drvdata(phy); -+ -+ airoha_phy_pma0_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, -+ PCIE_PMA_SW_RST); -+ airoha_phy_pma1_clear_bits(pcie_phy, REG_PCIE_PMA_SW_RESET, -+ PCIE_PMA_SW_RST); -+ airoha_phy_csr_2l_clear_bits(pcie_phy, REG_CSR_2L_JCPLL_SSC, -+ CSR_2L_PXP_JCPLL_SSC_PHASE_INI | -+ CSR_2L_PXP_JCPLL_SSC_TRI_EN | -+ CSR_2L_PXP_JCPLL_SSC_EN); -+ -+ return 0; -+} -+ -+static const struct phy_ops airoha_pcie_phy_ops = { -+ .init = airoha_pcie_phy_init, -+ .exit = airoha_pcie_phy_exit, -+ .owner = THIS_MODULE, -+}; -+ -+static int airoha_pcie_phy_probe(struct platform_device *pdev) -+{ -+ struct airoha_pcie_phy *pcie_phy; -+ struct device *dev = &pdev->dev; -+ struct phy_provider *provider; -+ -+ pcie_phy = devm_kzalloc(dev, sizeof(*pcie_phy), GFP_KERNEL); -+ if (!pcie_phy) -+ return -ENOMEM; -+ -+ pcie_phy->csr_2l = devm_platform_ioremap_resource_byname(pdev, "csr-2l"); -+ if (IS_ERR(pcie_phy->csr_2l)) -+ return dev_err_probe(dev, PTR_ERR(pcie_phy->csr_2l), -+ "Failed to map phy-csr-2l base\n"); -+ -+ pcie_phy->pma0 = devm_platform_ioremap_resource_byname(pdev, "pma0"); -+ if (IS_ERR(pcie_phy->pma0)) -+ return dev_err_probe(dev, PTR_ERR(pcie_phy->pma0), -+ "Failed to map phy-pma0 base\n"); -+ -+ pcie_phy->pma1 = devm_platform_ioremap_resource_byname(pdev, "pma1"); -+ if (IS_ERR(pcie_phy->pma1)) -+ return dev_err_probe(dev, PTR_ERR(pcie_phy->pma1), -+ "Failed to map phy-pma1 base\n"); -+ -+ pcie_phy->phy = devm_phy_create(dev, dev->of_node, &airoha_pcie_phy_ops); -+ if (IS_ERR(pcie_phy->phy)) -+ return dev_err_probe(dev, PTR_ERR(pcie_phy->phy), -+ "Failed to create PCIe phy\n"); -+ -+ pcie_phy->p0_xr_dtime = -+ devm_platform_ioremap_resource_byname(pdev, "p0-xr-dtime"); -+ if (IS_ERR(pcie_phy->p0_xr_dtime)) -+ return dev_err_probe(dev, PTR_ERR(pcie_phy->p0_xr_dtime), -+ "Failed to map P0 Tx-Rx dtime base\n"); -+ -+ pcie_phy->p1_xr_dtime = -+ devm_platform_ioremap_resource_byname(pdev, "p1-xr-dtime"); -+ if (IS_ERR(pcie_phy->p1_xr_dtime)) -+ return dev_err_probe(dev, PTR_ERR(pcie_phy->p1_xr_dtime), -+ "Failed to map P1 Tx-Rx dtime base\n"); -+ -+ pcie_phy->rx_aeq = devm_platform_ioremap_resource_byname(pdev, "rx-aeq"); -+ if (IS_ERR(pcie_phy->rx_aeq)) -+ return dev_err_probe(dev, PTR_ERR(pcie_phy->rx_aeq), -+ "Failed to map Rx AEQ base\n"); -+ -+ pcie_phy->dev = dev; -+ phy_set_drvdata(pcie_phy->phy, pcie_phy); -+ -+ provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ if (IS_ERR(provider)) -+ return dev_err_probe(dev, PTR_ERR(provider), -+ "PCIe phy probe failed\n"); -+ -+ return 0; -+} -+ -+static const struct of_device_id airoha_pcie_phy_of_match[] = { -+ { .compatible = "airoha,en7581-pcie-phy" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, airoha_pcie_phy_of_match); -+ -+static struct platform_driver airoha_pcie_phy_driver = { -+ .probe = airoha_pcie_phy_probe, -+ .driver = { -+ .name = "airoha-pcie-phy", -+ .of_match_table = airoha_pcie_phy_of_match, -+ }, -+}; -+module_platform_driver(airoha_pcie_phy_driver); -+ -+MODULE_DESCRIPTION("Airoha PCIe PHY driver"); -+MODULE_AUTHOR("Lorenzo Bianconi "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/airoha/patches-6.12/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch b/target/linux/airoha/patches-6.12/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch deleted file mode 100644 index 8994927b077..00000000000 --- a/target/linux/airoha/patches-6.12/220-07-phy-airoha-Add-support-for-Airoha-AN7581-USB-PHY.patch +++ /dev/null @@ -1,667 +0,0 @@ -From fadd22890b239e5a251dbe47367cfbeb1ea105f7 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Feb 2025 13:28:40 +0100 -Subject: [PATCH 07/10] phy: airoha: Add support for Airoha AN7581 USB PHY - -Add support for Airoha AN7581 USB PHY driver. AN7581 supports up to 2 -USB port with USB 2.0 mode always supported and USB 3.0 mode available -only if the Serdes port is correctly configured for USB 3.0. - -The second USB port on the SoC can be both used for USB 3.0 operation or -PCIe. (toggled by the SCU SSR register and configured by the USB PHY -driver) - -If the USB 3.0 mode is not configured, the modes needs to be also -disabled in the xHCI node or the driver will report unsable clock and -fail probe. - -Also USB 3.0 PHY instance are provided only if the airoha,serdes-port -and airoha,scu property is defined in DT, if it's not then USB 3.0 PHY -is assumed not supported. - -For USB 2.0 Slew Rate calibration, airoha,usb2-monitor-clk-sel is -mandatory and is used to select the monitor clock for calibration. - -Normally it's 1 for USB port 1 and 2 for USB port 2. - -Signed-off-by: Christian Marangi ---- - MAINTAINERS | 1 + - drivers/phy/airoha/Kconfig | 10 + - drivers/phy/airoha/Makefile | 1 + - drivers/phy/airoha/phy-airoha-usb.c | 597 ++++++++++++++++++++++++++++ - 4 files changed, 609 insertions(+) - create mode 100644 drivers/phy/airoha/phy-airoha-usb.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -756,6 +756,7 @@ M: Christian Marangi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* SCU */ -+#define AIROHA_SCU_SSTR 0x9c -+#define AIROHA_SCU_SSTR_USB_PCIE_SEL BIT(3) -+#define AIROHA_SCU_SSTR_USB_PCIE_SEL_PCIE FIELD_PREP_CONST(AIROHA_SCU_SSTR_USB_PCIE_SEL, 0x0) -+#define AIROHA_SCU_SSTR_USB_PCIE_SEL_USB FIELD_PREP_CONST(AIROHA_SCU_SSTR_USB_PCIE_SEL, 0x1) -+ -+/* U2PHY */ -+#define AIROHA_USB_PHY_FMCR0 0x100 -+#define AIROHA_USB_PHY_MONCLK_SEL GENMASK(27, 26) -+#define AIROHA_USB_PHY_MONCLK_SEL0 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x0) -+#define AIROHA_USB_PHY_MONCLK_SEL1 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x1) -+#define AIROHA_USB_PHY_MONCLK_SEL2 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x2) -+#define AIROHA_USB_PHY_MONCLK_SEL3 FIELD_PREP_CONST(AIROHA_USB_PHY_MONCLK_SEL, 0x3) -+#define AIROHA_USB_PHY_FREQDET_EN BIT(24) -+#define AIROHA_USB_PHY_CYCLECNT GENMASK(23, 0) -+#define AIROHA_USB_PHY_FMMONR0 0x10c -+#define AIROHA_USB_PHY_USB_FM_OUT GENMASK(31, 0) -+#define AIROHA_USB_PHY_FMMONR1 0x110 -+#define AIROHA_USB_PHY_FRCK_EN BIT(8) -+ -+#define AIROHA_USB_PHY_USBPHYACR4 0x310 -+#define AIROHA_USB_PHY_USB20_FS_CR GENMASK(10, 8) -+#define AIROHA_USB_PHY_USB20_FS_CR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x0) -+#define AIROHA_USB_PHY_USB20_FS_CR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x2) -+#define AIROHA_USB_PHY_USB20_FS_CR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x4) -+#define AIROHA_USB_PHY_USB20_FS_CR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_CR, 0x6) -+#define AIROHA_USB_PHY_USB20_FS_SR GENMASK(2, 0) -+#define AIROHA_USB_PHY_USB20_FS_SR_MAX FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x0) -+#define AIROHA_USB_PHY_USB20_FS_SR_NORMAL FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x2) -+#define AIROHA_USB_PHY_USB20_FS_SR_SMALLER FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x4) -+#define AIROHA_USB_PHY_USB20_FS_SR_MIN FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_FS_SR, 0x6) -+#define AIROHA_USB_PHY_USBPHYACR5 0x314 -+#define AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN BIT(15) -+#define AIROHA_USB_PHY_USB20_HSTX_SRCTRL GENMASK(14, 12) -+#define AIROHA_USB_PHY_USBPHYACR6 0x318 -+#define AIROHA_USB_PHY_USB20_BC11_SW_EN BIT(23) -+#define AIROHA_USB_PHY_USB20_DISCTH GENMASK(7, 4) -+#define AIROHA_USB_PHY_USB20_DISCTH_400 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x0) -+#define AIROHA_USB_PHY_USB20_DISCTH_420 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x1) -+#define AIROHA_USB_PHY_USB20_DISCTH_440 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x2) -+#define AIROHA_USB_PHY_USB20_DISCTH_460 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x3) -+#define AIROHA_USB_PHY_USB20_DISCTH_480 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x4) -+#define AIROHA_USB_PHY_USB20_DISCTH_500 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x5) -+#define AIROHA_USB_PHY_USB20_DISCTH_520 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x6) -+#define AIROHA_USB_PHY_USB20_DISCTH_540 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x7) -+#define AIROHA_USB_PHY_USB20_DISCTH_560 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x8) -+#define AIROHA_USB_PHY_USB20_DISCTH_580 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0x9) -+#define AIROHA_USB_PHY_USB20_DISCTH_600 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xa) -+#define AIROHA_USB_PHY_USB20_DISCTH_620 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xb) -+#define AIROHA_USB_PHY_USB20_DISCTH_640 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xc) -+#define AIROHA_USB_PHY_USB20_DISCTH_660 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xd) -+#define AIROHA_USB_PHY_USB20_DISCTH_680 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xe) -+#define AIROHA_USB_PHY_USB20_DISCTH_700 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_DISCTH, 0xf) -+#define AIROHA_USB_PHY_USB20_SQTH GENMASK(3, 0) -+#define AIROHA_USB_PHY_USB20_SQTH_85 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x0) -+#define AIROHA_USB_PHY_USB20_SQTH_90 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x1) -+#define AIROHA_USB_PHY_USB20_SQTH_95 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x2) -+#define AIROHA_USB_PHY_USB20_SQTH_100 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x3) -+#define AIROHA_USB_PHY_USB20_SQTH_105 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x4) -+#define AIROHA_USB_PHY_USB20_SQTH_110 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x5) -+#define AIROHA_USB_PHY_USB20_SQTH_115 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x6) -+#define AIROHA_USB_PHY_USB20_SQTH_120 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x7) -+#define AIROHA_USB_PHY_USB20_SQTH_125 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x8) -+#define AIROHA_USB_PHY_USB20_SQTH_130 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0x9) -+#define AIROHA_USB_PHY_USB20_SQTH_135 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xa) -+#define AIROHA_USB_PHY_USB20_SQTH_140 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xb) -+#define AIROHA_USB_PHY_USB20_SQTH_145 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xc) -+#define AIROHA_USB_PHY_USB20_SQTH_150 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xd) -+#define AIROHA_USB_PHY_USB20_SQTH_155 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xe) -+#define AIROHA_USB_PHY_USB20_SQTH_160 FIELD_PREP_CONST(AIROHA_USB_PHY_USB20_SQTH, 0xf) -+ -+#define AIROHA_USB_PHY_U2PHYDTM1 0x36c -+#define AIROHA_USB_PHY_FORCE_IDDIG BIT(9) -+#define AIROHA_USB_PHY_IDDIG BIT(1) -+ -+#define AIROHA_USB_PHY_GPIO_CTLD 0x80c -+#define AIROHA_USB_PHY_C60802_GPIO_CTLD GENMASK(31, 0) -+#define AIROHA_USB_PHY_SSUSB_IP_SW_RST BIT(31) -+#define AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN BIT(30) -+#define AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST BIT(29) -+#define AIROHA_USB_PHY_SSUSB_SW_RST BIT(28) -+ -+#define AIROHA_USB_PHY_U3_PHYA_REG0 0xb00 -+#define AIROHA_USB_PHY_SSUSB_BG_DIV GENMASK(29, 28) -+#define AIROHA_USB_PHY_SSUSB_BG_DIV_2 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x0) -+#define AIROHA_USB_PHY_SSUSB_BG_DIV_4 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x1) -+#define AIROHA_USB_PHY_SSUSB_BG_DIV_8 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x2) -+#define AIROHA_USB_PHY_SSUSB_BG_DIV_16 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_BG_DIV, 0x3) -+#define AIROHA_USB_PHY_U3_PHYA_REG1 0xb04 -+#define AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE GENMASK(25, 10) -+#define AIROHA_USB_PHY_U3_PHYA_REG6 0xb18 -+#define AIROHA_USB_PHY_SSUSB_CDR_RESERVE GENMASK(31, 24) -+#define AIROHA_USB_PHY_U3_PHYA_REG8 0xb20 -+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY GENMASK(7, 6) -+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x0) -+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_64 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x1) -+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_128 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x2) -+#define AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_216 FIELD_PREP_CONST(AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, 0x3) -+ -+#define AIROHA_USB_PHY_U3_PHYA_DA_REG19 0xc38 -+#define AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3 GENMASK(15, 0) -+ -+#define AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT 1024 -+#define AIROHA_USB_PHY_REF_CK 20 -+#define AIROHA_USB_PHY_U2_SR_COEF 28 -+#define AIROHA_USB_PHY_U2_SR_COEF_DIVISOR 1000 -+ -+#define AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION 0x5 -+#define AIROHA_USB_PHY_FREQDET_SLEEP 1000 /* 1ms */ -+#define AIROHA_USB_PHY_FREQDET_TIMEOUT (AIROHA_USB_PHY_FREQDET_SLEEP * 10) -+ -+struct airoha_usb_phy_instance { -+ struct phy *phy; -+ u32 type; -+}; -+ -+enum airoha_usb_phy_instance_type { -+ AIROHA_PHY_USB2, -+ AIROHA_PHY_USB3, -+ -+ AIROHA_PHY_USB_MAX, -+}; -+ -+struct airoha_usb_phy_priv { -+ struct device *dev; -+ struct regmap *regmap; -+ struct regmap *scu; -+ -+ unsigned int monclk_sel; -+ unsigned int serdes_port; -+ -+ struct airoha_usb_phy_instance *phys[AIROHA_PHY_USB_MAX]; -+}; -+ -+static void airoha_usb_phy_u2_slew_rate_calibration(struct airoha_usb_phy_priv *priv) -+{ -+ u32 fm_out; -+ u32 srctrl; -+ -+ /* Enable HS TX SR calibration */ -+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, -+ AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); -+ -+ usleep_range(1000, 1500); -+ -+ /* Enable Free run clock */ -+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, -+ AIROHA_USB_PHY_FRCK_EN); -+ -+ /* Select Monitor Clock */ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, -+ AIROHA_USB_PHY_MONCLK_SEL, -+ FIELD_PREP(AIROHA_USB_PHY_MONCLK_SEL, -+ priv->monclk_sel)); -+ -+ /* Set cyclecnt */ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, -+ AIROHA_USB_PHY_CYCLECNT, -+ FIELD_PREP(AIROHA_USB_PHY_CYCLECNT, -+ AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT)); -+ -+ /* Enable Frequency meter */ -+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, -+ AIROHA_USB_PHY_FREQDET_EN); -+ -+ /* Timeout can happen and we will apply workaround at the end */ -+ regmap_read_poll_timeout(priv->regmap, AIROHA_USB_PHY_FMMONR0, fm_out, -+ fm_out, AIROHA_USB_PHY_FREQDET_SLEEP, -+ AIROHA_USB_PHY_FREQDET_TIMEOUT); -+ -+ /* Disable Frequency meter */ -+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMCR0, -+ AIROHA_USB_PHY_FREQDET_EN); -+ -+ /* Disable Free run clock */ -+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_FMMONR1, -+ AIROHA_USB_PHY_FRCK_EN); -+ -+ /* Disable HS TX SR calibration */ -+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, -+ AIROHA_USB_PHY_USB20_HSTX_SRCAL_EN); -+ -+ usleep_range(1000, 1500); -+ -+ /* Frequency was not detected, use default SR calibration value */ -+ if (!fm_out) { -+ srctrl = AIROHA_USB_PHY_DEFAULT_SR_CALIBRATION; -+ dev_err(priv->dev, "Frequency not detected, using default SR calibration.\n"); -+ } else { -+ /* (1024 / FM_OUT) * REF_CK * U2_SR_COEF (round to the nearest digits) */ -+ srctrl = AIROHA_USB_PHY_REF_CK * AIROHA_USB_PHY_U2_SR_COEF; -+ srctrl = (srctrl * AIROHA_USB_PHY_U2_FM_DET_CYCLE_CNT) / fm_out; -+ srctrl = DIV_ROUND_CLOSEST(srctrl, AIROHA_USB_PHY_U2_SR_COEF_DIVISOR); -+ dev_dbg(priv->dev, "SR calibration applied: %x\n", srctrl); -+ } -+ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR5, -+ AIROHA_USB_PHY_USB20_HSTX_SRCTRL, -+ FIELD_PREP(AIROHA_USB_PHY_USB20_HSTX_SRCTRL, srctrl)); -+} -+ -+static void airoha_usb_phy_u2_init(struct airoha_usb_phy_priv *priv) -+{ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, -+ AIROHA_USB_PHY_USB20_FS_CR, -+ AIROHA_USB_PHY_USB20_FS_CR_MIN); -+ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR4, -+ AIROHA_USB_PHY_USB20_FS_SR, -+ AIROHA_USB_PHY_USB20_FS_SR_NORMAL); -+ -+ /* FIXME: evaluate if needed */ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, -+ AIROHA_USB_PHY_USB20_SQTH, -+ AIROHA_USB_PHY_USB20_SQTH_130); -+ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, -+ AIROHA_USB_PHY_USB20_DISCTH, -+ AIROHA_USB_PHY_USB20_DISCTH_600); -+ -+ /* Enable the USB port and then disable after calibration */ -+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, -+ AIROHA_USB_PHY_USB20_BC11_SW_EN); -+ -+ airoha_usb_phy_u2_slew_rate_calibration(priv); -+ -+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, -+ AIROHA_USB_PHY_USB20_BC11_SW_EN); -+ -+ usleep_range(1000, 1500); -+} -+ -+/* -+ * USB 3.0 mode can only work if USB serdes is correctly set. -+ * This is validated in xLate function. -+ */ -+static void airoha_usb_phy_u3_init(struct airoha_usb_phy_priv *priv) -+{ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG8, -+ AIROHA_USB_PHY_SSUSB_CDR_RST_DLY, -+ AIROHA_USB_PHY_SSUSB_CDR_RST_DLY_32); -+ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG6, -+ AIROHA_USB_PHY_SSUSB_CDR_RESERVE, -+ FIELD_PREP(AIROHA_USB_PHY_SSUSB_CDR_RESERVE, 0xe)); -+ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG0, -+ AIROHA_USB_PHY_SSUSB_BG_DIV, -+ AIROHA_USB_PHY_SSUSB_BG_DIV_4); -+ -+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_REG1, -+ FIELD_PREP(AIROHA_USB_PHY_SSUSB_XTAL_TOP_RESERVE, 0x600)); -+ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U3_PHYA_DA_REG19, -+ AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, -+ FIELD_PREP(AIROHA_USB_PHY_SSUSB_PLL_SSC_DELTA1_U3, 0x43)); -+} -+ -+static int airoha_usb_phy_init(struct phy *phy) -+{ -+ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); -+ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); -+ -+ switch (instance->type) { -+ case PHY_TYPE_USB2: -+ airoha_usb_phy_u2_init(priv); -+ break; -+ case PHY_TYPE_USB3: -+ if (phy_get_mode(phy) == PHY_MODE_PCIE) -+ return 0; -+ -+ airoha_usb_phy_u3_init(priv); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_u2_power_on(struct airoha_usb_phy_priv *priv) -+{ -+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, -+ AIROHA_USB_PHY_USB20_BC11_SW_EN); -+ -+ usleep_range(1000, 1500); -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_u3_power_on(struct airoha_usb_phy_priv *priv) -+{ -+ regmap_clear_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, -+ AIROHA_USB_PHY_SSUSB_IP_SW_RST | -+ AIROHA_USB_PHY_MCU_BUS_CK_GATE_EN | -+ AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST | -+ AIROHA_USB_PHY_SSUSB_SW_RST); -+ -+ usleep_range(1000, 1500); -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_power_on(struct phy *phy) -+{ -+ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); -+ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); -+ -+ switch (instance->type) { -+ case PHY_TYPE_USB2: -+ airoha_usb_phy_u2_power_on(priv); -+ break; -+ case PHY_TYPE_USB3: -+ if (phy_get_mode(phy) == PHY_MODE_PCIE) -+ return 0; -+ -+ airoha_usb_phy_u3_power_on(priv); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_u2_power_off(struct airoha_usb_phy_priv *priv) -+{ -+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_USBPHYACR6, -+ AIROHA_USB_PHY_USB20_BC11_SW_EN); -+ -+ usleep_range(1000, 1500); -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_u3_power_off(struct airoha_usb_phy_priv *priv) -+{ -+ regmap_set_bits(priv->regmap, AIROHA_USB_PHY_GPIO_CTLD, -+ AIROHA_USB_PHY_SSUSB_IP_SW_RST | -+ AIROHA_USB_PHY_FORCE_SSUSB_IP_SW_RST); -+ -+ usleep_range(1000, 1500); -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_power_off(struct phy *phy) -+{ -+ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); -+ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); -+ -+ switch (instance->type) { -+ case PHY_TYPE_USB2: -+ airoha_usb_phy_u2_power_off(priv); -+ break; -+ case PHY_TYPE_USB3: -+ if (phy_get_mode(phy) == PHY_MODE_PCIE) -+ return 0; -+ -+ airoha_usb_phy_u3_power_off(priv); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_u2_set_mode(struct airoha_usb_phy_priv *priv, -+ enum phy_mode mode) -+{ -+ u32 val; -+ -+ /* -+ * For Device and Host mode, enable force IDDIG. -+ * For Device set IDDIG, for Host clear IDDIG. -+ * For OTG disable force and clear IDDIG bit while at it. -+ */ -+ switch (mode) { -+ case PHY_MODE_USB_DEVICE: -+ val = AIROHA_USB_PHY_IDDIG; -+ break; -+ case PHY_MODE_USB_HOST: -+ val = AIROHA_USB_PHY_FORCE_IDDIG | -+ AIROHA_USB_PHY_FORCE_IDDIG; -+ break; -+ case PHY_MODE_USB_OTG: -+ val = 0; -+ break; -+ default: -+ return 0; -+ } -+ -+ regmap_update_bits(priv->regmap, AIROHA_USB_PHY_U2PHYDTM1, -+ AIROHA_USB_PHY_FORCE_IDDIG | -+ AIROHA_USB_PHY_IDDIG, val); -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_u3_set_mode(struct airoha_usb_phy_priv *priv, -+ enum phy_mode mode) -+{ -+ u32 sel; -+ -+ /* Only USB2 supports PCIe mode */ -+ if (mode == PHY_MODE_PCIE && -+ priv->serdes_port != AIROHA_SCU_SERDES_USB2) -+ return -EINVAL; -+ -+ if (mode == PHY_MODE_PCIE) -+ sel = AIROHA_SCU_SSTR_USB_PCIE_SEL_PCIE; -+ else -+ sel = AIROHA_SCU_SSTR_USB_PCIE_SEL_USB; -+ -+ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, -+ AIROHA_SCU_SSTR_USB_PCIE_SEL, sel); -+ -+ return 0; -+} -+ -+static int airoha_usb_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) -+{ -+ struct airoha_usb_phy_instance *instance = phy_get_drvdata(phy); -+ struct airoha_usb_phy_priv *priv = dev_get_drvdata(phy->dev.parent); -+ -+ switch (instance->type) { -+ case PHY_TYPE_USB2: -+ return airoha_usb_phy_u2_set_mode(priv, mode); -+ case PHY_TYPE_USB3: -+ return airoha_usb_phy_u3_set_mode(priv, mode); -+ default: -+ return 0; -+ } -+} -+ -+static struct phy *airoha_usb_phy_xlate(struct device *dev, -+ const struct of_phandle_args *args) -+{ -+ struct airoha_usb_phy_priv *priv = dev_get_drvdata(dev); -+ struct airoha_usb_phy_instance *instance = NULL; -+ unsigned int index, phy_type; -+ -+ if (args->args_count != 1) { -+ dev_err(dev, "invalid number of cells in 'phy' property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ phy_type = args->args[0]; -+ if (!(phy_type == PHY_TYPE_USB2 || phy_type == PHY_TYPE_USB3)) { -+ dev_err(dev, "unsupported device type: %d\n", phy_type); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ for (index = 0; index < AIROHA_PHY_USB_MAX; index++) -+ if (priv->phys[index] && -+ phy_type == priv->phys[index]->type) { -+ instance = priv->phys[index]; -+ break; -+ } -+ -+ if (!instance) { -+ dev_err(dev, "failed to find appropriate phy\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return instance->phy; -+} -+ -+static const struct phy_ops airoha_phy = { -+ .init = airoha_usb_phy_init, -+ .power_on = airoha_usb_phy_power_on, -+ .power_off = airoha_usb_phy_power_off, -+ .set_mode = airoha_usb_phy_set_mode, -+ .owner = THIS_MODULE, -+}; -+ -+static const struct regmap_config airoha_usb_phy_regmap_config = { -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+}; -+ -+static int airoha_usb_phy_probe(struct platform_device *pdev) -+{ -+ struct phy_provider *phy_provider; -+ struct airoha_usb_phy_priv *priv; -+ struct device *dev = &pdev->dev; -+ unsigned int index; -+ void *base; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->dev = dev; -+ -+ ret = of_property_read_u32(dev->of_node, "airoha,usb2-monitor-clk-sel", -+ &priv->monclk_sel); -+ if (ret) -+ return dev_err_probe(dev, ret, "Monitor clock selection is mandatory for USB PHY calibration.\n"); -+ -+ if (priv->monclk_sel > 3) -+ return dev_err_probe(dev, -EINVAL, "only 4 Monitor clock are selectable on the SoC.\n"); -+ -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ priv->regmap = devm_regmap_init_mmio(dev, base, &airoha_usb_phy_regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ platform_set_drvdata(pdev, priv); -+ -+ for (index = 0; index < AIROHA_PHY_USB_MAX; index++) { -+ enum airoha_usb_phy_instance_type phy_type; -+ struct airoha_usb_phy_instance *instance; -+ -+ switch (index) { -+ case AIROHA_PHY_USB2: -+ phy_type = PHY_TYPE_USB2; -+ break; -+ case AIROHA_PHY_USB3: -+ phy_type = PHY_TYPE_USB3; -+ break; -+ } -+ -+ /* Skip registering USB3 instance if not supported */ -+ if (phy_type == PHY_TYPE_USB3) { -+ ret = of_property_read_u32(dev->of_node, "airoha,serdes-port", -+ &priv->serdes_port); -+ if (ret) -+ continue; -+ -+ /* With Serdes Port property, SCU is required */ -+ priv->scu = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "airoha,scu"); -+ if (IS_ERR(priv->scu)) -+ return dev_err_probe(dev, PTR_ERR(priv->scu), "failed to get SCU syscon.\n"); -+ } -+ -+ instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL); -+ if (!instance) -+ return -ENOMEM; -+ -+ instance->type = phy_type; -+ priv->phys[index] = instance; -+ -+ instance->phy = devm_phy_create(dev, NULL, &airoha_phy); -+ if (IS_ERR(instance->phy)) -+ return dev_err_probe(dev, PTR_ERR(instance->phy), "failed to create phy\n"); -+ -+ phy_set_drvdata(instance->phy, instance); -+ } -+ -+ phy_provider = devm_of_phy_provider_register(&pdev->dev, airoha_usb_phy_xlate); -+ -+ return PTR_ERR_OR_ZERO(phy_provider); -+} -+ -+static const struct of_device_id airoha_phy_id_table[] = { -+ { .compatible = "airoha,an7581-usb-phy" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, airoha_phy_id_table); -+ -+static struct platform_driver airoha_usb_driver = { -+ .probe = airoha_usb_phy_probe, -+ .driver = { -+ .name = "airoha-usb-phy", -+ .of_match_table = airoha_phy_id_table, -+ }, -+}; -+ -+module_platform_driver(airoha_usb_driver); -+ -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Airoha USB PHY driver"); diff --git a/target/linux/airoha/patches-6.12/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch b/target/linux/airoha/patches-6.12/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch deleted file mode 100644 index 3756f7643ae..00000000000 --- a/target/linux/airoha/patches-6.12/220-08-usb-host-add-ARCH_AIROHA-in-XHCI-MTK-dependency.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3d3a406dea89b789dfb550bd05d0eba5ae926755 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Feb 2025 14:17:06 +0100 -Subject: [PATCH 08/10] usb: host: add ARCH_AIROHA in XHCI MTK dependency - -Airoha SoC use the same register map a logic of the Mediatek xHCI -driver, hence add it to the dependency list to permit compilation also -on this ARCH. - -Signed-off-by: Christian Marangi ---- - drivers/usb/host/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/host/Kconfig -+++ b/drivers/usb/host/Kconfig -@@ -71,7 +71,7 @@ config USB_XHCI_HISTB - config USB_XHCI_MTK - tristate "xHCI support for MediaTek SoCs" - select MFD_SYSCON -- depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || COMPILE_TEST -+ depends on (MIPS && SOC_MT7621) || ARCH_MEDIATEK || ARCH_AIROHA || COMPILE_TEST - help - Say 'Y' to enable the support for the xHCI host controller - found in MediaTek SoCs. diff --git a/target/linux/airoha/patches-6.12/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch b/target/linux/airoha/patches-6.12/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch deleted file mode 100644 index 19d168db645..00000000000 --- a/target/linux/airoha/patches-6.12/220-10-PCI-mediatek-gen3-set-PHY-mode-for-Airoha-EN7581.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 112c6ea7ac356dab16e11084f2183e653a289e91 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 28 Oct 2025 12:35:41 +0100 -Subject: [PATCH 10/10] PCI: mediatek-gen3: set PHY mode for Airoha EN7581 - -For the Airoha EN7581 SoC, the 3rd PCIe line is attached to a special -PHY that can be both used for USB 3.0 operation or PCIe. - -Configure the PHY for PCIe operation before init it to correctly -configure the SCU Serdes register. - -This permits correct functionality and enumeration of PCIe devices on -the 3rd PCIe line present on the SoC. - -Signed-off-by: Christian Marangi ---- - drivers/pci/controller/pcie-mediatek-gen3.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -925,6 +925,12 @@ static int mtk_pcie_en7581_power_up(stru - size = lower_32_bits(resource_size(entry->res)); - regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); - -+ err = phy_set_mode(pcie->phy, PHY_MODE_PCIE); -+ if (err) { -+ dev_err(dev, "failed to set PHY mode\n"); -+ return err; -+ } -+ - /* - * Unlike the other MediaTek Gen3 controllers, the Airoha EN7581 - * requires PHY initialization and power-on before PHY reset deassert. diff --git a/target/linux/airoha/patches-6.12/310-02-net-airoha-deassert-XSI-line-on-hw-init.patch b/target/linux/airoha/patches-6.12/310-02-net-airoha-deassert-XSI-line-on-hw-init.patch deleted file mode 100644 index a75e06f944a..00000000000 --- a/target/linux/airoha/patches-6.12/310-02-net-airoha-deassert-XSI-line-on-hw-init.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5cb5f11469dfcbd7568fbca8b79c0f20a21cfbf5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 17 Jan 2025 10:09:15 +0100 -Subject: [PATCH 2/9] net: airoha: deassert XSI line on hw init - -In preparation for phylink support, deassert XSI line as we will naw -make actual use of them for external PHY/SFP cage support. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1487,6 +1487,10 @@ static int airoha_hw_init(struct platfor - if (err) - return err; - -+ err = reset_control_bulk_deassert(eth->soc->num_xsi_rsts, eth->xsi_rsts); -+ if (err) -+ return err; -+ - msleep(20); - err = reset_control_bulk_deassert(ARRAY_SIZE(eth->rsts), eth->rsts); - if (err) diff --git a/target/linux/airoha/patches-6.12/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch b/target/linux/airoha/patches-6.12/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch deleted file mode 100644 index d5a2ba9d1ae..00000000000 --- a/target/linux/airoha/patches-6.12/310-03-net-airoha-add-reference-for-SPORT-GDM4-in-qdma_get_.patch +++ /dev/null @@ -1,31 +0,0 @@ -From ad29054f9b0e96e30a5d0bb6967d1204b8ea8bd1 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 17 Jan 2025 10:12:02 +0100 -Subject: [PATCH 3/9] net: airoha: add reference for SPORT GDM4 in - qdma_get_gdm_port - -Add SPORT reference in get gdm port as the on receive the SPORT 0x18 is -assigned for the GDM4 port. - -While at it also add comments to better identify GDM1 ports. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -574,8 +574,11 @@ static int airoha_qdma_get_gdm_port(stru - - sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); - switch (sport) { -+ case 0x18: -+ port = 3; /* GDM4 */ -+ break; - case 0x10 ... 0x14: -- port = 0; -+ port = 0; /* GDM1 */ - break; - case 0x2 ... 0x4: - port = sport - 1; diff --git a/target/linux/airoha/patches-6.12/310-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch b/target/linux/airoha/patches-6.12/310-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch deleted file mode 100644 index cd774e11eac..00000000000 --- a/target/linux/airoha/patches-6.12/310-06-net-airoha-add-initial-fixup-for-GDM3-4-port-support.patch +++ /dev/null @@ -1,40 +0,0 @@ -From a3cd6eb3259282a68b608fc923121460c0d3d2f7 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 17 Jan 2025 10:35:41 +0100 -Subject: [PATCH 6/9] net: airoha: add initial fixup for GDM3/4 port support - -GDM3 and GDM4 require different configuration for max long frame -definition, needs the QDMA to strip CRC on RX and require the SPORT to -be enabled to correctly be identified. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 12 ++++++++++-- - drivers/net/ethernet/airoha/airoha_regs.h | 1 + - 2 files changed, 11 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -498,8 +498,10 @@ static int airoha_fe_init(struct airoha_ - FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | - FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); - -- airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK); -- airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), -+ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK); -+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), -+ GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK); - - airoha_fe_crsn_qsel_init(eth); - -@@ -1719,7 +1721,8 @@ static int airoha_dev_open(struct net_de - if (err) - return err; - -- if (netdev_uses_dsa(dev)) -+ /* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */ -+ if (netdev_uses_dsa(dev) || port->id > 2) - airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), - GDM_STAG_EN_MASK); - else diff --git a/target/linux/airoha/patches-6.12/310-07-airoha-ethernet-drop-xsi-mac-reset.patch b/target/linux/airoha/patches-6.12/310-07-airoha-ethernet-drop-xsi-mac-reset.patch deleted file mode 100644 index 0ecba241d80..00000000000 --- a/target/linux/airoha/patches-6.12/310-07-airoha-ethernet-drop-xsi-mac-reset.patch +++ /dev/null @@ -1,33 +0,0 @@ -From fecb65813ddf52abf310bc2227a0ac869dc897d1 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 29 Jan 2025 14:47:41 +0100 -Subject: [PATCH 1/3] airoha: ethernet: drop xsi-mac reset - -In preparation for support for Ethernet and PON PCS, drop the xsi-mac -reset from airoha_eth. This reset is related to the Ethernet PCS and -should be handled in the dedicated driver. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++----- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - 2 files changed, 5 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -3196,7 +3196,6 @@ static void airoha_remove(struct platfor - } - - static const char * const en7581_xsi_rsts_names[] = { -- "xsi-mac", - "hsi0-mac", - "hsi1-mac", - "hsi-mac", -@@ -3250,7 +3249,6 @@ static u32 airoha_en7581_get_vip_port(st - } - - static const char * const an7583_xsi_rsts_names[] = { -- "xsi-mac", - "hsi0-mac", - "hsi1-mac", - "xfp-mac", diff --git a/target/linux/airoha/patches-6.12/310-09-net-pcs-airoha-add-PCS-driver-for-Airoha-AN7581-SoC.patch b/target/linux/airoha/patches-6.12/310-09-net-pcs-airoha-add-PCS-driver-for-Airoha-AN7581-SoC.patch deleted file mode 100644 index 1f3137f70b0..00000000000 --- a/target/linux/airoha/patches-6.12/310-09-net-pcs-airoha-add-PCS-driver-for-Airoha-AN7581-SoC.patch +++ /dev/null @@ -1,4793 +0,0 @@ -From 5d11640584dd24a1ba23e767c6929314c8ac50cf Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 17 Jan 2025 12:40:32 +0100 -Subject: [PATCH 1/2] net: pcs: airoha: add PCS driver for Airoha AN7581 SoC - -Add PCS driver for Airoha AN7581 SoC for Ethernet/PON/PCIe/USB SERDES -and permit usage of external PHY or connected SFP cage. Supported modes -are USXGMII, 10G-BASER, 2500BASE-X, 1000BASE-X and SGMII. - -The driver probe and register the various needed registers and register as -a PCS provider for fwnode usage. - -Signed-off-by: Christian Marangi ---- - drivers/net/pcs/Kconfig | 2 + - drivers/net/pcs/Makefile | 2 + - drivers/net/pcs/airoha/Kconfig | 12 + - drivers/net/pcs/airoha/Makefile | 7 + - drivers/net/pcs/airoha/pcs-airoha-common.c | 1313 ++++++++++++ - drivers/net/pcs/airoha/pcs-airoha.h | 1309 ++++++++++++ - drivers/net/pcs/airoha/pcs-an7581.c | 2093 ++++++++++++++++++++ - 7 files changed, 4738 insertions(+) - create mode 100644 drivers/net/pcs/airoha/Kconfig - create mode 100644 drivers/net/pcs/airoha/Makefile - create mode 100644 drivers/net/pcs/airoha/pcs-airoha-common.c - create mode 100644 drivers/net/pcs/airoha/pcs-airoha.h - create mode 100644 drivers/net/pcs/airoha/pcs-an7581.c - ---- a/drivers/net/pcs/Kconfig -+++ b/drivers/net/pcs/Kconfig -@@ -51,4 +51,6 @@ config PCS_RZN1_MIIC - on RZ/N1 SoCs. This PCS converts MII to RMII/RGMII or can be set in - pass-through mode for MII. - -+source "drivers/net/pcs/airoha/Kconfig" -+ - endmenu ---- a/drivers/net/pcs/Makefile -+++ b/drivers/net/pcs/Makefile -@@ -10,3 +10,5 @@ obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o - obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o - obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o - obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o -+ -+obj-$(CONFIG_PCS_AIROHA) += airoha/ ---- /dev/null -+++ b/drivers/net/pcs/airoha/Kconfig -@@ -0,0 +1,12 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+ -+config PCS_AIROHA -+ tristate -+ select FWNODE_PCS -+ -+config PCS_AIROHA_AN7581 -+ tristate "Airoha AN7581 PCS driver" -+ select PCS_AIROHA -+ help -+ This module provides helper to phylink for managing the Airoha -+ AN7581 PCS for SoC Ethernet and PON SERDES. ---- /dev/null -+++ b/drivers/net/pcs/airoha/Makefile -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+obj-y := pcs-airoha.o -+pcs-airoha-objs := pcs-airoha-common.o -+ifdef CONFIG_PCS_AIROHA_AN7581 -+pcs-airoha-objs += pcs-an7581.o -+endif ---- /dev/null -+++ b/drivers/net/pcs/airoha/pcs-airoha-common.c -@@ -0,0 +1,1312 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Christian Marangi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pcs-airoha.h" -+ -+static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv, -+ phy_interface_t interface) -+{ -+ u32 xsi_sel; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ xsi_sel = AIROHA_SCU_ETH_XSI_HSGMII; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ default: -+ xsi_sel = AIROHA_SCU_ETH_XSI_USXGMII; -+ } -+ -+ regmap_update_bits(priv->scu, AIROHA_SCU_SSR3, -+ AIROHA_SCU_ETH_XSI_SEL, -+ xsi_sel); -+} -+ -+static void airoha_pcs_setup_scu_pon(struct airoha_pcs_priv *priv, -+ phy_interface_t interface) -+{ -+ u32 xsi_sel, wan_sel; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ wan_sel = AIROHA_SCU_WAN_SEL_SGMII; -+ xsi_sel = AIROHA_SCU_PON_XSI_HSGMII; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ wan_sel = AIROHA_SCU_WAN_SEL_HSGMII; -+ xsi_sel = AIROHA_SCU_PON_XSI_HSGMII; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ default: -+ wan_sel = AIROHA_SCU_WAN_SEL_USXGMII; -+ xsi_sel = AIROHA_SCU_PON_XSI_USXGMII; -+ } -+ -+ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, -+ AIROHA_SCU_PON_XSI_SEL, -+ xsi_sel); -+ -+ regmap_update_bits(priv->scu, AIROHA_SCU_WAN_CONF, -+ AIROHA_SCU_WAN_SEL, -+ wan_sel); -+} -+ -+static void airoha_pcs_setup_scu_pcie(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ u32 xsi_sel; -+ -+ if (index == 0) { -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ xsi_sel = AIROHA_SCU_PCIE_XSI0_HSGMII; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ default: -+ xsi_sel = AIROHA_SCU_PCIE_XSI0_USXGMII; -+ } -+ -+ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, -+ AIROHA_SCU_PCIE_XSI0_SEL, -+ xsi_sel); -+ } else { -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ xsi_sel = AIROHA_SCU_PCIE_XSI1_HSGMII; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ default: -+ xsi_sel = AIROHA_SCU_PCIE_XSI1_USXGMII; -+ } -+ -+ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, -+ AIROHA_SCU_PCIE_XSI1_SEL, -+ xsi_sel); -+ } -+} -+ -+static int airoha_pcs_setup_scu(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ int ret; -+ -+ switch (data->port_type) { -+ case AIROHA_PCS_ETH: -+ airoha_pcs_setup_scu_eth(priv, interface); -+ break; -+ case AIROHA_PCS_PON: -+ airoha_pcs_setup_scu_pon(priv, interface); -+ break; -+ case AIROHA_PCS_PCIE: -+ airoha_pcs_setup_scu_pcie(priv, index, interface); -+ break; -+ case AIROHA_PCS_USB: -+ break; -+ } -+ -+ /* TODO better handle reset from MAC */ -+ ret = reset_control_bulk_assert(ARRAY_SIZE(priv->rsts), -+ priv->rsts); -+ if (ret) -+ return ret; -+ -+ ret = reset_control_bulk_deassert(ARRAY_SIZE(priv->rsts), -+ priv->rsts); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static void airoha_pcs_init_usxgmii(struct airoha_pcs_priv *priv, int index) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ -+ regmap_set_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, -+ AIROHA_PCS_HSGMII_XFI_SEL); -+ -+ /* Disable Hibernation */ -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1, -+ AIROHA_PCS_USXGMII_SPEED_SEL_H); -+ -+ /* FIXME: wait Airoha */ -+ /* Avoid PCS sending garbage to MAC in some HW revision (E0) */ -+ regmap_write(maps->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); -+} -+ -+static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv, int index) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ -+ regmap_clear_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, -+ AIROHA_PCS_HSGMII_XFI_SEL); -+ -+ regmap_update_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, -+ AIROHA_PCS_TBI_10B_MODE, -+ priv->phy ? 0 : AIROHA_PCS_TBI_10B_MODE); -+} -+ -+static void airoha_pcs_init_sgmii(struct airoha_pcs_priv *priv, int index) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ -+ regmap_clear_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, -+ AIROHA_PCS_HSGMII_XFI_SEL); -+ -+ regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, -+ AIROHA_PCS_TBI_10B_MODE); -+ -+ regmap_update_bits(maps->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6, -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L, -+ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L, 0x07070707)); -+ -+ regmap_update_bits(maps->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8, -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C, -+ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C, 0xff)); -+} -+ -+static void airoha_pcs_init(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ airoha_pcs_init_sgmii(priv, index); -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ airoha_pcs_init_hsgmii(priv, index); -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ airoha_pcs_init_usxgmii(priv, index); -+ break; -+ default: -+ return; -+ } -+} -+ -+static void airoha_pcs_interrupt_init_sgmii(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ -+ /* Disable every interrupt */ -+ regmap_clear_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, -+ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT | -+ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT | -+ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT | -+ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT | -+ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT); -+ -+ /* Clear interrupt */ -+ regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, -+ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR); -+ -+ regmap_clear_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT, -+ AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR | -+ AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR); -+} -+ -+static void airoha_pcs_interrupt_init_usxgmii(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ -+ /* Disable every Interrupt */ -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_0, -+ AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN | -+ AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN | -+ AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN | -+ AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN); -+ -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_1, -+ AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN | -+ AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN | -+ AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN | -+ AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN); -+ -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_2, -+ AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN | -+ AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN | -+ AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN | -+ AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN); -+ -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_3, -+ AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN | -+ AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN | -+ AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN | -+ AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN); -+ -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTRL_4, -+ AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN); -+ -+ /* Clear any pending interrupt */ -+ regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_2, -+ AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT | -+ AIROHA_PCS_USXGMII_R_TYPE_E_INT | -+ AIROHA_PCS_USXGMII_R_TYPE_T_INT | -+ AIROHA_PCS_USXGMII_R_TYPE_D_INT); -+ -+ regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_3, -+ AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT | -+ AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT | -+ AIROHA_PCS_USXGMII_LINK_UP_ST_INT | -+ AIROHA_PCS_USXGMII_HI_BER_ST_INT); -+ -+ regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_INT_STA_4, -+ AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT); -+ -+ /* Interrupt saddly seems to be not weel supported for Link Down. -+ * PCS Poll is a must to correctly read and react on Cable Deatch -+ * as only cable attach interrupt are fired and Link Down interrupt -+ * are fired only in special case like AN restart. -+ */ -+} -+ -+static void airoha_pcs_interrupt_init(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ return airoha_pcs_interrupt_init_sgmii(priv, index); -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ return airoha_pcs_interrupt_init_usxgmii(priv, index); -+ default: -+ return; -+ } -+} -+ -+static void airoha_pcs_get_state_sgmii(struct airoha_pcs_priv *priv, -+ int index, struct phylink_link_state *state) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ u32 bmsr, lpa; -+ -+ regmap_read(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1, -+ &bmsr); -+ regmap_read(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5, -+ &lpa); -+ -+ bmsr = (AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE | -+ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT | -+ AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY | -+ AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS) & bmsr; -+ lpa = AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY & lpa; -+ -+ phylink_mii_c22_pcs_decode_state(state, bmsr, lpa); -+} -+ -+static void airoha_pcs_get_state_hsgmii(struct airoha_pcs_priv *priv, int index, -+ struct phylink_link_state *state) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ u32 bmsr; -+ -+ regmap_read(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1, -+ &bmsr); -+ -+ bmsr = (AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE | -+ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT | -+ AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY | -+ AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS) & bmsr; -+ -+ state->link = !!(bmsr & BMSR_LSTATUS); -+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); -+ state->speed = SPEED_2500; -+ state->duplex = DUPLEX_FULL; -+} -+ -+static void airoha_pcs_get_state_usxgmii(struct airoha_pcs_priv *priv, int index, -+ struct phylink_link_state *state) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ u32 an_done, lpa; -+ -+ /* Trigger HW workaround if needed. If an error is reported, -+ * consider link down and test again later. -+ */ -+ if (data->rxlock_workaround && data->rxlock_workaround(priv, index)) { -+ state->link = false; -+ return; -+ } -+ -+ /* Toggle AN Status */ -+ regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, -+ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, -+ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); -+ -+ regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &lpa); -+ regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_2, &an_done); -+ -+ state->link = !!(lpa & MDIO_USXGMII_LINK); -+ state->an_complete = !!(an_done & AIROHA_PCS_USXGMII_PCS_AN_COMPLETE); -+ -+ phylink_decode_usxgmii_word(state, lpa); -+} -+ -+static void airoha_pcs_get_state_10gbaser(struct airoha_pcs_priv *priv, int index, -+ struct phylink_link_state *state) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ u32 status, curr_mode; -+ -+ /* Toggle AN Status */ -+ regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, -+ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6, -+ AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS); -+ -+ regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_BASE_R_10GB_T_PCS_STUS_1, -+ &status); -+ regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_STATS_0, &curr_mode); -+ -+ state->link = !!(status & AIROHA_PCS_USXGMII_RX_LINK_STUS); -+ -+ switch (curr_mode & AIROHA_PCS_USXGMII_CUR_USXGMII_MODE) { -+ case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_10G: -+ state->speed = SPEED_10000; -+ break; -+ case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_5G: -+ state->speed = SPEED_5000; -+ break; -+ case AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_2_5G: -+ state->speed = SPEED_2500; -+ break; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ return; -+ } -+ -+ state->duplex = DUPLEX_FULL; -+} -+ -+static void airoha_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); -+ struct airoha_pcs_priv *priv = port->priv; -+ -+ switch (state->interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ airoha_pcs_get_state_sgmii(priv, port->index, state); -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ airoha_pcs_get_state_hsgmii(priv, port->index, state); -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ airoha_pcs_get_state_usxgmii(priv, port->index, state); -+ break; -+ case PHY_INTERFACE_MODE_10GBASER: -+ airoha_pcs_get_state_10gbaser(priv, port->index, state); -+ break; -+ default: -+ return; -+ } -+} -+ -+static int airoha_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); -+ struct airoha_pcs_priv *priv = port->priv; -+ const struct airoha_pcs_match_data *data; -+ struct airoha_pcs_maps *maps; -+ int index = port->index; -+ u32 rate_adapt; -+ int ret; -+ -+ maps = &priv->maps[port->index]; -+ priv->interface = interface; -+ data = priv->data; -+ -+ /* Apply Analog and Digital configuration for PCS */ -+ if (data->bringup) { -+ ret = data->bringup(priv, index, interface); -+ if (ret) -+ return ret; -+ } -+ -+ /* Set final configuration for various modes */ -+ airoha_pcs_init(priv, index, interface); -+ -+ /* Configure Interrupt for various modes */ -+ airoha_pcs_interrupt_init(priv, index, interface); -+ -+ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN | -+ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN; -+ -+ if (interface == PHY_INTERFACE_MODE_SGMII) -+ rate_adapt |= AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS | -+ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS; -+ -+ /* AN Auto Settings (Rate Adaptation) */ -+ regmap_update_bits(maps->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0, -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS | -+ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS | -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN | -+ AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN, rate_adapt); -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII || -+ interface == PHY_INTERFACE_MODE_10GBASER) { -+ if (interface == PHY_INTERFACE_MODE_USXGMII) { -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) -+ regmap_set_bits(maps->usxgmii_pcs, -+ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, -+ AIROHA_PCS_USXGMII_AN_ENABLE); -+ else -+ regmap_clear_bits(maps->usxgmii_pcs, -+ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, -+ AIROHA_PCS_USXGMII_AN_ENABLE); -+ -+ regmap_clear_bits(maps->usxgmii_pcs, -+ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, -+ AIROHA_PCS_USXGMII_RATE_UPDATE_MODE); -+ } else { -+ regmap_clear_bits(maps->usxgmii_pcs, -+ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, -+ AIROHA_PCS_USXGMII_AN_ENABLE); -+ -+ regmap_set_bits(maps->usxgmii_pcs, -+ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, -+ AIROHA_PCS_USXGMII_RATE_UPDATE_MODE); -+ } -+ } -+ -+ /* Clear any force bit that my be set by bootloader */ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ interface == PHY_INTERFACE_MODE_1000BASEX || -+ interface == PHY_INTERFACE_MODE_2500BASEX) { -+ regmap_clear_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0, -+ AIROHA_PCS_LINK_MODE_P0 | -+ AIROHA_PCS_FORCE_SPD_MODE_P0 | -+ AIROHA_PCS_FORCE_LINKDOWN_P0 | -+ AIROHA_PCS_FORCE_LINKUP_P0); -+ } -+ -+ /* Toggle Rate Adaption for SGMII/HSGMII mode */ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ interface == PHY_INTERFACE_MODE_1000BASEX || -+ interface == PHY_INTERFACE_MODE_2500BASEX) { -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) -+ regmap_clear_bits(maps->hsgmii_rate_adp, -+ AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0, -+ AIROHA_PCS_HSGMII_P0_DIS_MII_MODE); -+ else -+ regmap_set_bits(maps->hsgmii_rate_adp, -+ AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0, -+ AIROHA_PCS_HSGMII_P0_DIS_MII_MODE); -+ } -+ -+ /* Setup AN Link Timer */ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ interface == PHY_INTERFACE_MODE_1000BASEX) { -+ u32 an_timer; -+ -+ an_timer = phylink_get_link_timer_ns(interface); -+ -+ /* Value needs to be shifted by 4, seems value is internally * 16 */ -+ regmap_update_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11, -+ AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER, -+ FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER, -+ an_timer >> 4)); -+ -+ regmap_update_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_3, -+ AIROHA_PCS_HSGMII_PCS_LINK_STSTIME, -+ FIELD_PREP(AIROHA_PCS_HSGMII_PCS_LINK_STSTIME, -+ an_timer >> 4)); -+ } -+ -+ /* Setup SGMII AN and advertisement in DEV_ABILITY */ -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ int advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -+ advertising); -+ if (advertise < 0) -+ return advertise; -+ -+ regmap_update_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4, -+ AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY, -+ FIELD_PREP(AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY, -+ advertise)); -+ -+ regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, -+ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); -+ } else { -+ regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, -+ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); -+ } -+ } -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) { -+ regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, -+ AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE); -+ -+ regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, -+ AIROHA_PCS_HSGMII_PCS_TX_ENABLE); -+ } -+ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ interface == PHY_INTERFACE_MODE_1000BASEX) { -+ u32 if_mode = AIROHA_PCS_HSGMII_AN_SIDEBAND_EN; -+ -+ /* Toggle SGMII or 1000base-x mode */ -+ if (interface == PHY_INTERFACE_MODE_SGMII) -+ if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_EN; -+ -+ if (neg_mode & PHYLINK_PCS_NEG_INBAND) -+ regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, -+ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); -+ else -+ regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, -+ AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS); -+ -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ /* Clear force speed bits and MAC mode */ -+ regmap_clear_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, -+ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 | -+ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 | -+ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 | -+ AIROHA_PCS_HSGMII_PCS_MAC_MODE | -+ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL | -+ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT); -+ } else { -+ /* Enable compatibility with MAC PCS Layer */ -+ if_mode |= AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN; -+ -+ /* AN off force rate adaption, speed is set later in Link Up */ -+ regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, -+ AIROHA_PCS_HSGMII_PCS_MAC_MODE | -+ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT); -+ } -+ -+ regmap_update_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, -+ AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0, if_mode); -+ -+ regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, -+ AIROHA_PCS_HSGMII_PCS_TX_ENABLE | -+ AIROHA_PCS_HSGMII_PCS_MODE2_EN); -+ } -+ -+ if (interface == PHY_INTERFACE_MODE_1000BASEX && -+ neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_1, -+ AIROHA_PCS_SGMII_SEND_AN_ERR_EN); -+ -+ regmap_set_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37, -+ AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE); -+ } -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) { -+ regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, -+ AIROHA_PCS_HSGMII_AN_SGMII_RESET_PHY); -+ } -+ -+ /* Configure Flow Control on XFI */ -+ regmap_update_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN, -+ permit_pause_to_mac ? -+ AIROHA_PCS_XFI_TX_FC_EN | AIROHA_PCS_XFI_RX_FC_EN : -+ 0); -+ -+ return 0; -+} -+ -+static void airoha_pcs_an_restart(struct phylink_pcs *pcs) -+{ -+ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); -+ struct airoha_pcs_priv *priv = port->priv; -+ struct airoha_pcs_maps *maps; -+ -+ maps = &priv->maps[port->index]; -+ -+ switch (priv->interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ regmap_set_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, -+ AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART); -+ udelay(3); -+ regmap_clear_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0, -+ AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART); -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ regmap_set_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, -+ AIROHA_PCS_USXGMII_AN_RESTART); -+ udelay(3); -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0, -+ AIROHA_PCS_USXGMII_AN_RESTART); -+ default: -+ return; -+ } -+} -+ -+static void airoha_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, -+ phy_interface_t interface, int speed, int duplex) -+{ -+ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); -+ struct airoha_pcs_priv *priv = port->priv; -+ const struct airoha_pcs_match_data *data; -+ struct airoha_pcs_maps *maps; -+ -+ maps = &priv->maps[port->index]; -+ data = priv->data; -+ -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ regmap_update_bits(maps->hsgmii_rate_adp, -+ AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1, -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR | -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, -+ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0x0) | -+ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x0)); -+ udelay(1); -+ regmap_update_bits(maps->hsgmii_rate_adp, -+ AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1, -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR | -+ AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, -+ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR, 0xf) | -+ FIELD_PREP(AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR, 0x5)); -+ } -+ } else { -+ if (interface == PHY_INTERFACE_MODE_USXGMII || -+ interface == PHY_INTERFACE_MODE_10GBASER) { -+ u32 mode; -+ u32 rate_adapt; -+ -+ switch (speed) { -+ case SPEED_10000: -+ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000; -+ mode = AIROHA_PCS_USXGMII_MODE_10000; -+ break; -+ case SPEED_5000: -+ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000; -+ mode = AIROHA_PCS_USXGMII_MODE_5000; -+ break; -+ case SPEED_2500: -+ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500; -+ mode = AIROHA_PCS_USXGMII_MODE_2500; -+ break; -+ case SPEED_1000: -+ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000; -+ mode = AIROHA_PCS_USXGMII_MODE_1000; -+ break; -+ case SPEED_100: -+ rate_adapt = AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100; -+ mode = AIROHA_PCS_USXGMII_MODE_100; -+ break; -+ } -+ -+ /* Force USXGMII to selected speed */ -+ regmap_update_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, -+ AIROHA_PCS_USXGMII_MODE, mode); -+ -+ if (interface == PHY_INTERFACE_MODE_10GBASER) -+ regmap_update_bits(maps->hsgmii_rate_adp, AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11, -+ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN | -+ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, -+ AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN | -+ rate_adapt); -+ } -+ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ interface == PHY_INTERFACE_MODE_1000BASEX) { -+ u32 force_speed; -+ u32 rate_adapt; -+ -+ switch (speed) { -+ case SPEED_1000: -+ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000; -+ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000; -+ break; -+ case SPEED_100: -+ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100; -+ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100; -+ break; -+ case SPEED_10: -+ force_speed = AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10; -+ rate_adapt = AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10; -+ break; -+ } -+ -+ regmap_update_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_CTROL_6, -+ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 | -+ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 | -+ AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 | -+ AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, -+ force_speed | rate_adapt); -+ } -+ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ interface == PHY_INTERFACE_MODE_2500BASEX) { -+ u32 ck_gen_mode; -+ u32 speed_reg; -+ u32 if_mode; -+ -+ switch (speed) { -+ case SPEED_2500: -+ speed_reg = AIROHA_PCS_LINK_MODE_P0_2_5G; -+ break; -+ case SPEED_1000: -+ speed_reg = AIROHA_PCS_LINK_MODE_P0_1G; -+ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000; -+ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000; -+ break; -+ case SPEED_100: -+ speed_reg = AIROHA_PCS_LINK_MODE_P0_100M; -+ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100; -+ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100; -+ break; -+ case SPEED_10: -+ speed_reg = AIROHA_PCS_LINK_MODE_P0_100M; -+ if_mode = AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10; -+ ck_gen_mode = AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10; -+ break; -+ } -+ -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ regmap_update_bits(maps->hsgmii_an, AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13, -+ AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, -+ if_mode); -+ -+ regmap_update_bits(maps->hsgmii_pcs, AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE, -+ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE | -+ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL, -+ ck_gen_mode | -+ AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL); -+ } -+ -+ regmap_update_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0, -+ AIROHA_PCS_LINK_MODE_P0 | -+ AIROHA_PCS_FORCE_SPD_MODE_P0, -+ speed_reg | -+ AIROHA_PCS_FORCE_SPD_MODE_P0); -+ } -+ } -+ -+ if (data->link_up) -+ data->link_up(priv, port->index); -+ -+ /* BPI BMI enable */ -+ regmap_clear_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_RXMPI_STOP | -+ AIROHA_PCS_XFI_RXMBI_STOP | -+ AIROHA_PCS_XFI_TXMPI_STOP | -+ AIROHA_PCS_XFI_TXMBI_STOP); -+} -+ -+static void airoha_pcs_link_down(struct phylink_pcs *pcs) -+{ -+ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); -+ struct airoha_pcs_priv *priv = port->priv; -+ struct airoha_pcs_maps *maps; -+ -+ maps = &priv->maps[port->index]; -+ -+ /* MPI MBI disable */ -+ regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_RXMPI_STOP | -+ AIROHA_PCS_XFI_RXMBI_STOP | -+ AIROHA_PCS_XFI_TXMPI_STOP | -+ AIROHA_PCS_XFI_TXMBI_STOP); -+} -+ -+static void airoha_pcs_pre_config(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); -+ struct airoha_pcs_priv *priv = port->priv; -+ struct airoha_pcs_maps *maps; -+ -+ maps = &priv->maps[port->index]; -+ -+ /* Select HSGMII or USXGMII in SCU regs */ -+ airoha_pcs_setup_scu(priv, port->index, interface); -+ -+ /* MPI MBI disable */ -+ regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_RXMPI_STOP | -+ AIROHA_PCS_XFI_RXMBI_STOP | -+ AIROHA_PCS_XFI_TXMPI_STOP | -+ AIROHA_PCS_XFI_TXMBI_STOP); -+ -+ /* Write 1 to trigger reset and clear */ -+ regmap_clear_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST, -+ AIROHA_PCS_XFI_MAC_LOGIC_RST); -+ regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST, -+ AIROHA_PCS_XFI_MAC_LOGIC_RST); -+ -+ usleep_range(1000, 2000); -+ -+ /* Clear XFI MAC counter */ -+ regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_CNT_CLR, -+ AIROHA_PCS_XFI_GLB_CNT_CLR); -+} -+ -+static int airoha_pcs_post_config(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ struct airoha_pcs_port *port = to_airoha_pcs_port(pcs); -+ struct airoha_pcs_priv *priv = port->priv; -+ struct airoha_pcs_maps *maps; -+ -+ maps = &priv->maps[port->index]; -+ -+ /* Frag disable */ -+ regmap_update_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_RX_FRAG_LEN, -+ FIELD_PREP(AIROHA_PCS_XFI_RX_FRAG_LEN, 31)); -+ regmap_update_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_TX_FRAG_LEN, -+ FIELD_PREP(AIROHA_PCS_XFI_TX_FRAG_LEN, 31)); -+ -+ /* IPG NUM */ -+ regmap_update_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_IPG_NUM, -+ FIELD_PREP(AIROHA_PCS_XFI_IPG_NUM, 10)); -+ -+ /* Enable TX/RX flow control */ -+ regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_TX_FC_EN); -+ regmap_set_bits(maps->pcs_mac, AIROHA_PCS_XFI_MAC_XFI_GIB_CFG, -+ AIROHA_PCS_XFI_RX_FC_EN); -+ -+ return 0; -+} -+ -+static unsigned int airoha_pcs_inband_caps(struct phylink_pcs *pcs, -+ phy_interface_t interface) -+{ -+ return LINK_INBAND_ENABLE | LINK_INBAND_DISABLE; -+} -+ -+static const struct phylink_pcs_ops airoha_pcs_ops = { -+ .pcs_inband_caps = airoha_pcs_inband_caps, -+ .pcs_pre_config = airoha_pcs_pre_config, -+ .pcs_post_config = airoha_pcs_post_config, -+ .pcs_get_state = airoha_pcs_get_state, -+ .pcs_config = airoha_pcs_config, -+ .pcs_an_restart = airoha_pcs_an_restart, -+ .pcs_link_up = airoha_pcs_link_up, -+ .pcs_link_down = airoha_pcs_link_down, -+}; -+ -+static int airoha_pcs_init_named_regmap(struct platform_device *pdev, -+ const char *name, struct regmap **regmap) -+{ -+ struct regmap_config regmap_config = { }; -+ void *base; -+ -+ base = devm_platform_ioremap_resource_byname(pdev, name); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ regmap_config.name = name; -+ regmap_config.reg_bits = 32, -+ regmap_config.val_bits = 32, -+ regmap_config.reg_stride = 4, -+ -+ *regmap = devm_regmap_init_mmio(&pdev->dev, base, ®map_config); -+ -+ return PTR_ERR_OR_ZERO(*regmap); -+} -+ -+static int airoha_pcs_alloc_maps(struct platform_device *pdev, -+ struct airoha_pcs_priv *priv) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[0]; -+ int ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac", &maps->pcs_mac); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an", &maps->hsgmii_an); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs", &maps->hsgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp", &maps->hsgmii_rate_adp); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii", &maps->multi_sgmii); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "usxgmii", &maps->usxgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_pma", &priv->pcs_pma[0]); -+ if (ret) -+ return ret; -+ -+ return airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); -+} -+ -+static int airoha_pcs_usb_alloc_maps(struct platform_device *pdev, -+ struct airoha_pcs_priv *priv) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[0]; -+ int ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac", &maps->pcs_mac); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an", &maps->hsgmii_an); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs", &maps->hsgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp", &maps->hsgmii_rate_adp); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii", &maps->multi_sgmii); -+ if (ret) -+ return ret; -+ -+ return airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); -+} -+ -+static int airoha_pcs_pcie_alloc_maps(struct platform_device *pdev, -+ struct airoha_pcs_priv *priv) -+{ -+ struct airoha_pcs_maps *maps = priv->maps; -+ int ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac0", &maps[0].pcs_mac); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an0", &maps[0].hsgmii_an); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs0", &maps[0].hsgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp0", &maps[0].hsgmii_rate_adp); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii0", &maps[0].multi_sgmii); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "usxgmii0", &maps[0].usxgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac1", &maps[1].pcs_mac); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an1", &maps[1].hsgmii_an); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs1", &maps[1].hsgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp1", &maps[1].hsgmii_rate_adp); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii1", &maps[1].multi_sgmii); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "usxgmii1", &maps[1].usxgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_pma0", &priv->pcs_pma[0]); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_pma1", &priv->pcs_pma[1]); -+ if (ret) -+ return ret; -+ -+ return airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); -+} -+ -+static struct phylink_pcs *airoha_pcs_get(struct fwnode_reference_args *pcsspec, -+ void *data) -+{ -+ struct airoha_pcs_priv *priv = data; -+ struct device *dev = priv->dev; -+ int index = 0; -+ -+ switch (priv->data->port_type) { -+ case AIROHA_PCS_ETH: -+ case AIROHA_PCS_PON: -+ case AIROHA_PCS_USB: -+ if (pcsspec->nargs) { -+ dev_err(dev, "invalid number of cells in 'pcs' property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ break; -+ case AIROHA_PCS_PCIE: -+ if (pcsspec->nargs != 1) { -+ dev_err(dev, "invalid number of cells in 'pcs' property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ break; -+ } -+ -+ if (pcsspec->nargs) -+ index = pcsspec->args[0]; -+ -+ return &priv->ports[index].pcs; -+} -+ -+static int airoha_pcs_probe(struct platform_device *pdev) -+{ -+ const struct airoha_pcs_match_data *data; -+ struct device *dev = &pdev->dev; -+ struct airoha_pcs_priv *priv; -+ int index, ret; -+ -+ data = of_device_get_match_data(dev); -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->ports = devm_kcalloc(dev, data->num_port, -+ sizeof(*priv->ports), GFP_KERNEL); -+ if (!priv->ports) -+ return -ENOMEM; -+ -+ priv->dev = dev; -+ priv->data = data; -+ -+ if (data->port_type == AIROHA_PCS_USB) { -+ struct phy *phy; -+ -+ phy = devm_phy_get(dev, NULL); -+ if (IS_ERR(phy)) -+ return dev_err_probe(dev, PTR_ERR(phy), "failed to get phy\n"); -+ -+ priv->phy = phy; -+ } -+ -+ switch (data->port_type) { -+ case AIROHA_PCS_ETH: -+ case AIROHA_PCS_PON: -+ ret = airoha_pcs_alloc_maps(pdev, priv); -+ if (ret) -+ return ret; -+ -+ break; -+ case AIROHA_PCS_PCIE: -+ ret = airoha_pcs_pcie_alloc_maps(pdev, priv); -+ if (ret) -+ return ret; -+ -+ break; -+ case AIROHA_PCS_USB: -+ ret = airoha_pcs_usb_alloc_maps(pdev, priv); -+ if (ret) -+ return ret; -+ -+ break; -+ } -+ -+ if (data->alloc_regmap_fields) { -+ ret = data->alloc_regmap_fields(priv); -+ if (ret) -+ return ret; -+ } -+ -+ /* SCU is used to toggle XFI or HSGMII in global SoC registers */ -+ if (!priv->phy) { -+ priv->scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,scu"); -+ if (IS_ERR(priv->scu)) -+ return PTR_ERR(priv->scu); -+ } -+ -+ priv->rsts[0].id = "mac"; -+ priv->rsts[1].id = "phy"; -+ ret = devm_reset_control_bulk_get_optional_exclusive(dev, ARRAY_SIZE(priv->rsts), -+ priv->rsts); -+ if (ret) -+ return dev_err_probe(dev, ret, "failed to get bulk reset lines\n"); -+ -+ /* For Ethernet PCS, read the AN7581 SoC revision to check if -+ * manual rx calibration is needed. This is only limited to -+ * any SoC revision before E2. -+ */ -+ if (device_is_compatible(dev, "airoha,an7581-pcs-eth")) { -+ u32 val; -+ -+ ret = regmap_read(priv->scu, AIROHA_SCU_PDIDR, &val); -+ if (ret) -+ return ret; -+ -+ if (FIELD_GET(AIROHA_SCU_PRODUCT_ID, val) < 0x2) -+ priv->manual_rx_calib = true; -+ } -+ -+ for (index = 0; index < data->num_port; index++) { -+ struct airoha_pcs_port *port = &priv->ports[index]; -+ -+ port->priv = priv; -+ port->index = index; -+ port->pcs.poll = true; -+ port->pcs.neg_mode = true; -+ port->pcs.ops = &airoha_pcs_ops; -+ -+ switch (data->port_type) { -+ case AIROHA_PCS_ETH: -+ case AIROHA_PCS_PON: -+ case AIROHA_PCS_PCIE: -+ __set_bit(PHY_INTERFACE_MODE_10GBASER, -+ port->pcs.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_USXGMII, -+ port->pcs.supported_interfaces); -+ fallthrough; -+ case AIROHA_PCS_USB: -+ __set_bit(PHY_INTERFACE_MODE_SGMII, -+ port->pcs.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, -+ port->pcs.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, -+ port->pcs.supported_interfaces); -+ break; -+ } -+ } -+ -+ platform_set_drvdata(pdev, priv); -+ -+ return fwnode_pcs_add_provider(dev_fwnode(dev), airoha_pcs_get, -+ priv); -+} -+ -+static void airoha_pcs_remove(struct platform_device *pdev) -+{ -+ struct airoha_pcs_priv *priv = platform_get_drvdata(pdev); -+ const struct airoha_pcs_match_data *data = priv->data; -+ int i; -+ -+ fwnode_pcs_del_provider(dev_fwnode(&pdev->dev)); -+ -+ rtnl_lock(); -+ -+ for (i = 0; i < data->num_port; i++) { -+ struct airoha_pcs_port *port = &priv->ports[i]; -+ -+ phylink_release_pcs(&port->pcs); -+ } -+ -+ rtnl_unlock(); -+} -+ -+static const struct airoha_pcs_match_data an7581_pcs_eth = { -+ .num_port = 1, -+ .port_type = AIROHA_PCS_ETH, -+ .alloc_regmap_fields = an7581_pcs_alloc_regmap_fields, -+ .bringup = an7581_pcs_bringup, -+ .link_up = an7581_pcs_phya_link_up, -+ .rxlock_workaround = an7581_pcs_rxlock_workaround, -+}; -+ -+static const struct airoha_pcs_match_data an7581_pcs_pon = { -+ .num_port = 1, -+ .port_type = AIROHA_PCS_PON, -+ .alloc_regmap_fields = an7581_pcs_alloc_regmap_fields, -+ .bringup = an7581_pcs_bringup, -+ .link_up = an7581_pcs_phya_link_up, -+}; -+ -+static const struct airoha_pcs_match_data an7581_pcs_pcie = { -+ .num_port = 2, -+ .port_type = AIROHA_PCS_PCIE, -+ .alloc_regmap_fields = an7581_pcs_pcie_alloc_regmap_fields, -+ .bringup = an7581_pcs_bringup, -+ .link_up = an7581_pcs_phya_link_up, -+}; -+ -+static const struct airoha_pcs_match_data an7581_pcs_usb = { -+ .num_port = 1, -+ .port_type = AIROHA_PCS_USB, -+ .bringup = an7581_pcs_usb_bringup, -+}; -+ -+static const struct of_device_id airoha_pcs_of_table[] = { -+ { .compatible = "airoha,an7581-pcs-eth", .data = &an7581_pcs_eth }, -+ { .compatible = "airoha,an7581-pcs-pon", .data = &an7581_pcs_pon }, -+ { .compatible = "airoha,an7581-pcs-pcie", .data = &an7581_pcs_pcie }, -+ { .compatible = "airoha,an7581-pcs-usb", .data = &an7581_pcs_usb }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, airoha_pcs_of_table); -+ -+static struct platform_driver airoha_pcs_driver = { -+ .driver = { -+ .name = "airoha-pcs", -+ .of_match_table = airoha_pcs_of_table, -+ }, -+ .probe = airoha_pcs_probe, -+ .remove = airoha_pcs_remove, -+}; -+module_platform_driver(airoha_pcs_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Airoha PCS driver"); -+MODULE_AUTHOR("Christian Marangi "); ---- /dev/null -+++ b/drivers/net/pcs/airoha/pcs-airoha.h -@@ -0,0 +1,1309 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Christian Marangi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* SCU*/ -+#define AIROHA_SCU_PDIDR 0x5c -+#define AIROHA_SCU_PRODUCT_ID GENMASK(15, 0) -+#define AIROHA_SCU_WAN_CONF 0x70 -+#define AIROHA_SCU_WAN_SEL GENMASK(7, 0) -+#define AIROHA_SCU_WAN_SEL_SGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x10) -+#define AIROHA_SCU_WAN_SEL_HSGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x11) -+#define AIROHA_SCU_WAN_SEL_USXGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x12) -+#define AIROHA_SCU_SSR3 0x94 -+#define AIROHA_SCU_ETH_XSI_SEL GENMASK(14, 13) -+#define AIROHA_SCU_ETH_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x1) -+#define AIROHA_SCU_ETH_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_ETH_XSI_SEL, 0x2) -+#define AIROHA_SCU_SSTR 0x9c -+#define AIROHA_SCU_PCIE_XSI0_SEL GENMASK(14, 13) -+#define AIROHA_SCU_PCIE_XSI0_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI0_SEL, 0x1) -+#define AIROHA_SCU_PCIE_XSI0_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI0_SEL, 0x2) -+#define AIROHA_SCU_PCIE_XSI1_SEL GENMASK(12, 11) -+#define AIROHA_SCU_PCIE_XSI1_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI1_SEL, 0x1) -+#define AIROHA_SCU_PCIE_XSI1_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PCIE_XSI1_SEL, 0x2) -+#define AIROHA_SCU_PON_XSI_SEL GENMASK(10, 9) -+#define AIROHA_SCU_PON_XSI_USXGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x1) -+#define AIROHA_SCU_PON_XSI_HSGMII FIELD_PREP_CONST(AIROHA_SCU_PON_XSI_SEL, 0x2) -+ -+/* XFI_MAC */ -+#define AIROHA_PCS_XFI_MAC_XFI_GIB_CFG 0x0 -+#define AIROHA_PCS_XFI_RX_FRAG_LEN GENMASK(26, 22) -+#define AIROHA_PCS_XFI_TX_FRAG_LEN GENMASK(21, 17) -+#define AIROHA_PCS_XFI_IPG_NUM GENMASK(15, 10) -+#define AIROHA_PCS_XFI_TX_FC_EN BIT(5) -+#define AIROHA_PCS_XFI_RX_FC_EN BIT(4) -+#define AIROHA_PCS_XFI_RXMPI_STOP BIT(3) -+#define AIROHA_PCS_XFI_RXMBI_STOP BIT(2) -+#define AIROHA_PCS_XFI_TXMPI_STOP BIT(1) -+#define AIROHA_PCS_XFI_TXMBI_STOP BIT(0) -+#define AIROHA_PCS_XFI_MAC_XFI_LOGIC_RST 0x10 -+#define AIROHA_PCS_XFI_MAC_LOGIC_RST BIT(0) -+#define AIROHA_PCS_XFI_MAC_XFI_MACADDRH 0x60 -+#define AIROHA_PCS_XFI_MAC_MACADDRH GENMASK(15, 0) -+#define AIROHA_PCS_XFI_MAC_XFI_MACADDRL 0x64 -+#define AIROHA_PCS_XFI_MAC_MACADDRL GENMASK(31, 0) -+#define AIROHA_PCS_XFI_MAC_XFI_CNT_CLR 0x100 -+#define AIROHA_PCS_XFI_GLB_CNT_CLR BIT(0) -+ -+/* HSGMII_AN */ -+#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_0 0x0 -+#define AIROHA_PCS_HSGMII_AN_SGMII_RESET_PHY BIT(15) -+#define AIROHA_PCS_HSGMII_AN_SGMII_RA_ENABLE BIT(12) -+#define AIROHA_PCS_HSGMII_AN_SGMII_AN_RESTART BIT(9) -+#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_1 0x4 /* BMSR */ -+#define AIROHA_PCS_HSGMII_AN_SGMII_UNIDIR_ABILITY BIT(6) -+#define AIROHA_PCS_HSGMII_AN_SGMII_AN_COMPLETE BIT(5) -+#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT BIT(4) -+#define AIROHA_PCS_HSGMII_AN_SGMII_AN_ABILITY BIT(3) -+#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_STATUS BIT(2) -+#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_4 0x10 -+#define AIROHA_PCS_HSGMII_AN_SGMII_DEV_ABILITY GENMASK(15, 0) -+#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_5 0x14 /* LPA */ -+#define AIROHA_PCS_HSGMII_AN_SGMII_PARTNER_ABILITY GENMASK(15, 0) -+#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_11 0x2c -+#define AIROHA_PCS_HSGMII_AN_SGMII_LINK_TIMER GENMASK(19, 0) -+#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_13 0x34 -+#define AIROHA_PCS_HSGMII_AN_SGMII_REMOTE_FAULT_DIS BIT(8) -+#define AIROHA_PCS_HSGMII_AN_SGMII_IF_MODE_5_0 GENMASK(5, 0) -+#define AIROHA_PCS_HSGMII_AN_SGMII_COMPAT_EN BIT(5) -+#define AIROHA_PCS_HSGMII_AN_DUPLEX_FORCE_MODE BIT(4) -+#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE GENMASK(3, 2) -+#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x2) -+#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x1) -+#define AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_AN_SPEED_FORCE_MODE, 0x0) -+#define AIROHA_PCS_HSGMII_AN_SIDEBAND_EN BIT(1) -+#define AIROHA_PCS_HSGMII_AN_SGMII_EN BIT(0) -+#define AIROHA_PCS_HSGMII_AN_SGMII_REG_AN_FORCE_CL37 0x60 -+#define AIROHA_PCS_HSGMII_AN_FORCE_AN_DONE BIT(0) -+ -+/* HSGMII_PCS */ -+#define AIROHA_PCS_HSGMII_PCS_CTROL_1 0x0 -+#define AIROHA_PCS_TBI_10B_MODE BIT(30) -+#define AIROHA_PCS_SGMII_SEND_AN_ERR_EN BIT(24) -+#define AIROHA_PCS_REMOTE_FAULT_DIS BIT(12) -+#define AIROHA_PCS_HSGMII_PCS_CTROL_3 0x8 -+#define AIROHA_PCS_HSGMII_PCS_LINK_STSTIME GENMASK(19, 0) -+#define AIROHA_PCS_HSGMII_PCS_CTROL_6 0x14 -+#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_10 BIT(14) -+#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_100 BIT(13) -+#define AIROHA_PCS_HSGMII_PCS_SGMII_SPD_FORCE_1000 BIT(12) -+#define AIROHA_PCS_HSGMII_PCS_MAC_MODE BIT(8) -+#define AIROHA_PCS_HSGMII_PCS_TX_ENABLE BIT(4) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL GENMASK(3, 2) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x0) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x1) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT_VAL, 0x2) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_RATEADAPT BIT(1) -+#define AIROHA_PCS_HSGMII_PCS_MODE2_EN BIT(0) -+#define AIROHA_PCS_HSGMII_PCS_HSGMII_MODE_INTERRUPT 0x20 -+#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT_CLEAR BIT(11) -+#define AIROHA_PCS_HSGMII_MODE2_REMOVE_FAULT_OCCUR_INT BIT(10) -+#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT_CLEAR BIT(9) -+#define AIROHA_PCS_HSGMII_MODE2_AN_CL37_TIMERDONE_INT BIT(8) -+#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT_CLEAR BIT(5) -+#define AIROHA_PCS_HSGMII_MODE2_AN_MIS_INT BIT(4) -+#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT_CLEAR BIT(3) -+#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT_CLEAR BIT(2) -+#define AIROHA_PCS_HSGMII_MODE2_RX_SYN_DONE_INT BIT(1) -+#define AIROHA_PCS_HSGMII_MODE2_AN_DONE_INT BIT(0) -+#define AIROHA_PCS_HSGMII_PCS_AN_SGMII_MODE_FORCE 0x24 -+#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE GENMASK(5, 4) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x0) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x1) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_10 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE, 0x2) -+#define AIROHA_PCS_HSGMII_PCS_FORCE_CUR_SGMII_MODE_SEL BIT(0) -+#define ARIOHA_PCS_HSGMII_PCS_STATE_2 0x104 -+#define AIROHA_PCS_HSGMII_PCS_RX_SYNC BIT(5) -+#define AIROHA_PCS_HSGMII_PCS_AN_DONE BIT(0) -+#define AIROHA_PCS_HSGMII_PCS_INT_STATE 0x15c -+#define AIROHA_PCS_HSGMII_PCS_MODE2_REMOTE_FAULT_OCCUR_INT BIT(4) -+#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_MLS BIT(3) -+#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_CL37_TIMERDONE_INT BIT(2) -+#define AIROHA_PCS_HSGMII_PCS_MODE2_RX_SYNC BIT(1) -+#define AIROHA_PCS_HSGMII_PCS_MODE2_AN_DONE BIT(0) -+ -+/* HSGMII_ANA */ -+#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_6 0x18 -+#define AIROHA_PCS_HSGMII_ANA_FORCE_CDR_BIC BIT(20) -+#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_8 0x20 -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTR GENMASK(11, 8) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD1 GENMASK(7, 4) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD0 GENMASK(3, 0) -+#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_11 0x2c -+#define AIROHA_PCS_HSGMII_ANA_TPHY_SPEED GENMASK(3, 2) -+#define AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_SGMII FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, 0x0) -+#define AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_HSGMII FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, 0x1) -+#define AIROHA_PCS_HSGMII_ANA_TPHY_MODE GENMASK(1, 0) -+#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_18 0x48 -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_BG_DIV GENMASK(28, 27) -+#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_19 0x4c -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE GENMASK(25, 10) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_HV GENMASK(15, 8) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_LV GENMASK(7, 0) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG GENMASK(2, 0) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_GND FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x0) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONFBK_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x1) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONPLL_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x2) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONREF_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x3) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_SSUSB_SYSPLL_CKMON FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x4) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_SSUSB_SYSPLL_FBCKMON FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x5) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_TX2500M_A FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x6) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_SSUSB_CDR_250M_CK FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_MONCKBG, 0x7) -+#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_24 0x60 -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RESERVE GENMASK(31, 24) -+#define AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_26 0x68 -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY GENMASK(7, 6) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_32 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x0) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_64 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x1) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_128 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x2) -+#define AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_216 FIELD_PREP_CONST(AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, 0x3) -+ -+/* MULTI_SGMII */ -+#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_EN_0 0x14 -+#define AIROHA_PCS_MULTI_SGMII_PCS_INT_EN_0 BIT(0) -+#define AIROHA_PCS_MULTI_SGMII_SGMII_STS_CTRL_0 0x18 -+#define AIROHA_PCS_LINK_MODE_P0 GENMASK(5, 4) -+#define AIROHA_PCS_LINK_MODE_P0_2_5G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x3) -+#define AIROHA_PCS_LINK_MODE_P0_1G FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x2) -+#define AIROHA_PCS_LINK_MODE_P0_100M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x1) -+#define AIROHA_PCS_LINK_MODE_P0_10M FIELD_PREP_CONST(AIROHA_PCS_LINK_MODE_P0, 0x0) -+#define AIROHA_PCS_FORCE_SPD_MODE_P0 BIT(2) -+#define AIROHA_PCS_FORCE_LINKDOWN_P0 BIT(1) -+#define AIROHA_PCS_FORCE_LINKUP_P0 BIT(0) -+#define AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0 0x100 -+#define AIROHA_PCS_HSGMII_XFI_SEL BIT(28) -+#define AIROHA_PCS_MULTI_SGMII_INTERRUPT_SEL 0x14c -+#define AIROHA_PCS_HSGMII_PCS_INT BIT(0) -+#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_15 0x43c -+#define AIROHA_PCS_LINK_STS_P0 BIT(3) -+#define AIROHA_PCS_SPEED_STS_P0 GENMASK(2, 0) -+#define AIROHA_PCS_SPEED_STS_P0_1G FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x2) -+#define AIROHA_PCS_SPEED_STS_P0_100M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x1) -+#define AIROHA_PCS_SPEED_STS_P0_10M FIELD_PREP_CONST(AIROHA_PCS_SPEED_STS_P0, 0x0) -+#define AIROHA_PCS_MULTI_SGMII_MSG_RX_STS_18 0x448 -+#define AIROHA_PCS_P0_SGMII_IS_10 BIT(2) -+#define AIROHA_PCS_P0_SGMII_IS_100 BIT(1) -+#define AIROHA_PCS_P0_SGMII_IS_1000 BIT(0) -+ -+/* HSGMII_RATE_ADP */ -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0 0x0 -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_BYPASS BIT(27) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_BYPASS BIT(26) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_EN BIT(4) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_TX_EN BIT(0) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_1 0x4 -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_WR_THR GENMASK(20, 16) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_RD_THR GENMASK(28, 24) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_6 0x18 -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_L GENMASK(31, 0) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_8 0x20 -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_RX_AFIFO_DOUT_C GENMASK(7, 0) -+#define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_11 0x2c -+#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_EN BIT(8) -+#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE GENMASK(15, 12) -+#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_10000 \ -+ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x0) -+#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_5000 \ -+ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x1) -+#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_2500 \ -+ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x2) -+#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_1000 \ -+ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x4) -+#define AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE_100 \ -+ FIELD_PREP_CONST(AIROHA_PCS_HSGMII_RATE_ADPT_FORCE_RATE_ADAPT_MODE, 0x6) -+#define AIROHA_PCS_HSGMII_RATE_ADP_P0_CTRL_0 0x100 -+#define AIROHA_PCS_HSGMII_P0_DIS_MII_MODE BIT(31) -+ -+/* USXGMII */ -+#define AIROHA_PCS_USXGMII_PCS_CTROL_1 0x0 -+#define AIROHA_PCS_USXGMII_SPEED_SEL_H BIT(13) -+#define AIROHA_PCS_USXGMII_PCS_STUS_1 0x4 -+#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS BIT(2) -+#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_UP \ -+ FIELD_PREP_CONST(AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS, 0x1) -+#define AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_DOWN \ -+ FIELD_PREP_CONST(AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS, 0x0) -+#define AIROHA_PCS_USXGMII_BASE_R_10GB_T_PCS_STUS_1 0x30 -+#define AIROHA_PCS_USXGMII_RX_LINK_STUS BIT(12) -+#define AIROHA_PCS_USXGMII_PRBS9_PATT_TST_ABILITY BIT(3) -+#define AIROHA_PCS_USXGMII_PRBS31_PATT_TST_ABILITY BIT(2) -+#define AIROHA_PCS_USXGMII_PCS_BLK_LK BIT(0) -+#define AIROHA_PCS_USGMII_VENDOR_DEFINE_116 0x22c -+#define AIROHA_PCS_USXGMII_PCS_CTRL_0 0x2c0 -+#define AIROHA_PCS_USXGMII_T_TYPE_T_INT_EN BIT(24) -+#define AIROHA_PCS_USXGMII_T_TYPE_D_INT_EN BIT(16) -+#define AIROHA_PCS_USXGMII_T_TYPE_C_INT_EN BIT(8) -+#define AIROHA_PCS_USXGMII_T_TYPE_S_INT_EN BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_CTRL_1 0x2c4 -+#define AIROHA_PCS_USXGMII_R_TYPE_C_INT_EN BIT(24) -+#define AIROHA_PCS_USXGMII_R_TYPE_S_INT_EN BIT(16) -+#define AIROHA_PCS_USXGMII_TXPCS_FSM_ENC_ERR_INT_EN BIT(8) -+#define AIROHA_PCS_USXGMII_T_TYPE_E_INT_EN BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_CTRL_2 0x2c8 -+#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT_EN BIT(24) -+#define AIROHA_PCS_USXGMII_R_TYPE_E_INT_EN BIT(16) -+#define AIROHA_PCS_USXGMII_R_TYPE_T_INT_EN BIT(8) -+#define AIROHA_PCS_USXGMII_R_TYPE_D_INT_EN BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_CTRL_3 0x2cc -+#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT_EN BIT(24) -+#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT_EN BIT(16) -+#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT_EN BIT(8) -+#define AIROHA_PCS_USXGMII_HI_BER_ST_INT_EN BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_INT_STA_2 0x2d8 -+#define AIROHA_PCS_USXGMII_RPCS_FSM_DEC_ERR_INT BIT(24) -+#define AIROHA_PCS_USXGMII_R_TYPE_E_INT BIT(16) -+#define AIROHA_PCS_USXGMII_R_TYPE_T_INT BIT(8) -+#define AIROHA_PCS_USXGMII_R_TYPE_D_INT BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_INT_STA_3 0x2dc -+#define AIROHA_PCS_USXGMII_FAIL_SYNC_XOR_ST_INT BIT(24) -+#define AIROHA_PCS_USXGMII_RX_BLOCK_LOCK_ST_INT BIT(16) -+#define AIROHA_PCS_USXGMII_LINK_UP_ST_INT BIT(8) -+#define AIROHA_PCS_USXGMII_HI_BER_ST_INT BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_CTRL_4 0x2e0 -+#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT_EN BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_INT_STA_4 0x2e4 -+#define AIROHA_PCS_USXGMII_LINK_DOWN_ST_INT BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_0 0x2f8 -+#define AIROHA_PCS_USXGMII_AN_RESTART BIT(8) -+#define AIROHA_PCS_USXGMII_AN_ENABLE BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_AN_STATS_0 0x310 -+#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE GENMASK(30, 28) -+#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_10G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x0) -+#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x1) -+#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_2_5G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x2) -+#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_1G FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x3) -+#define AIROHA_PCS_USXGMII_CUR_USXGMII_MODE_100M FIELD_PREP_CONST(AIROHA_PCS_USXGMII_CUR_USXGMII_MODE, 0x4) -+#define AIROHA_PCS_USXGMII_PARTNER_ABILITY GENMASK(15, 0) -+#define AIROHA_PCS_USXGMII_PCS_AN_STATS_2 0x318 -+#define AIROHA_PCS_USXGMII_PCS_AN_COMPLETE BIT(24) -+#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6 0x31c -+#define AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS BIT(0) -+#define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7 0x320 -+#define AIROHA_PCS_USXGMII_RATE_UPDATE_MODE BIT(12) -+#define AIROHA_PCS_USXGMII_MODE GENMASK(10, 8) -+#define AIROHA_PCS_USXGMII_MODE_10000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x0) -+#define AIROHA_PCS_USXGMII_MODE_5000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x1) -+#define AIROHA_PCS_USXGMII_MODE_2500 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x2) -+#define AIROHA_PCS_USXGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x3) -+#define AIROHA_PCS_USXGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x4) -+ -+/* PMA_PHYA */ -+#define AIROHA_PCS_ANA_PXP_CMN_EN 0x0 -+#define AIROHA_PCS_ANA_CMN_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN 0x4 -+#define AIROHA_PCS_ANA_JCPLL_CHP_IOFST GENMASK(29, 24) -+#define AIROHA_PCS_ANA_JCPLL_CHP_IBIAS GENMASK(21, 16) -+#define AIROHA_PCS_ANA_JCPLL_LPF_SHCK_EN BIT(8) -+#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR 0x8 -+#define AIROHA_PCS_ANA_JCPLL_LPF_BWR GENMASK(28, 24) -+#define AIROHA_PCS_ANA_JCPLL_LPF_BP GENMASK(20, 16) -+#define AIROHA_PCS_ANA_JCPLL_LPF_BC GENMASK(12, 8) -+#define AIROHA_PCS_ANA_JCPLL_LPF_BR GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC 0xc -+#define AIROHA_PCS_ANA_JCPLL_KBAND_DIV GENMASK(26, 24) -+#define AIROHA_PCS_ANA_JCPLL_KBAND_CODE GENMASK(23, 16) -+#define AIROHA_PCS_ANA_JCPLL_KBAND_OPTION BIT(8) -+#define AIROHA_PCS_ANA_JCPLL_LPF_BWC GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC 0x10 -+#define AIROHA_PCS_ANA_JCPLL_KBAND_KS GENMASK(17, 16) -+#define AIROHA_PCS_ANA_JCPLL_KBAND_KF GENMASK(9, 8) -+#define AIROHA_PCS_ANA_JCPLL_KBAND_KFC GENMASK(1, 0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE 0x14 -+#define AIROHA_PCS_ANA_JCPLL_POSTDIV_D5 BIT(24) -+#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) -+#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2 0x0 -+#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_3 0x1 -+#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_4 0x2 -+#define AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_1 0x3 -+#define AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY 0x1c -+#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS GENMASK(25, 24) -+#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23 0x0 -+#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_21 0x1 -+#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_19 0x2 -+#define AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_15 0x3 -+#define AIROHA_PCS_ANA_JCPLL_SDM_DI_EN BIT(16) -+#define AIROHA_PCS_ANA_JCPLL_PLL_RSTB BIT(8) -+#define AIROHA_PCS_ANA_JCPLL_RST_DLY GENMASK(2, 0) -+#define AIROHA_PCS_ANA_JCPLL_RST_DLY_20_25 0x1 -+#define AIROHA_PCS_ANA_JCPLL_RST_DLY_40_50 0x2 -+#define AIROHA_PCS_ANA_JCPLL_RST_DLY_80_100 0x3 -+#define AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200 0x4 -+#define AIROHA_PCS_ANA_JCPLL_RST_DLY_300_400 0x5 -+#define AIROHA_PCS_ANA_JCPLL_RST_DLY_600_800 0x6 -+#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM 0x20 -+#define AIROHA_PCS_ANA_JCPLL_SDM_OUT BIT(24) -+#define AIROHA_PCS_ANA_JCPLL_SDM_ORD GENMASK(17, 16) -+#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_INT 0x0 -+#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_1SDM 0x1 -+#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_2SDM 0x2 -+#define AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM 0x3 -+#define AIROHA_PCS_ANA_JCPLL_SDM_MODE GENMASK(9, 8) -+#define AIROHA_PCS_ANA_JCPLL_SDM_IFM BIT(0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN 0x24 -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_VREF GENMASK(28, 24) -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_2 0x0 -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4 0x1 -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_6 0x2 -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_8 0x3 -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_10 0x4 -+#define AIROHA_PCS_ANA_JCPLL_TCL_AMP_EN BIT(8) -+#define AIROHA_PCS_ANA_JCPLL_SDM_HREN BIT(0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN 0x28 -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW GENMASK(26, 24) -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_0_5 0x0 -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1 0x1 -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_2 0x2 -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_4 0x3 -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_8 0x4 -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_16 0x6 -+#define AIROHA_PCS_ANA_JCPLL_TCL_LPF_EN BIT(16) -+#define AIROHA_PCS_ANA_PXP_JCPLL_VCODIV 0x2c -+#define AIROHA_PCS_ANA_JCPLL_VCO_SCAPWR GENMASK(26, 24) -+#define AIROHA_PCS_ANA_JCPLL_VCO_HALFLSB_EN BIT(16) -+#define AIROHA_PCS_ANA_JCPLL_VCO_CFIX GENMASK(9, 8) -+#define AIROHA_PCS_ANA_JCPLL_VCODIV GENMASK(1, 0) -+#define AIROHA_PCS_ANA_JCPLL_VCODIV_1 0x0 -+#define AIROHA_PCS_ANA_JCPLL_VCODIV_2 0x1 -+#define AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR 0x30 -+#define AIROHA_PCS_ANA_JCPLL_SSC_PHASE_INI BIT(17) -+#define AIROHA_PCS_ANA_JCPLL_SSC_EN BIT(16) -+#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_L GENMASK(10, 8) -+#define AIROHA_PCS_ANA_JCPLL_VCO_VCOVAR_BIAS_H GENMASK(5, 3) -+#define AIROHA_PCS_ANA_JCPLL_VCO_TCLVAR GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN 0x34 -+#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA1 GENMASK(23, 8) -+#define AIROHA_PCS_ANA_JCPLL_SSC_TRI_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA 0x38 -+#define AIROHA_PCS_ANA_JCPLL_SSC_PERIOD GENMASK(31, 16) -+#define AIROHA_PCS_ANA_JCPLL_SSC_DELTA GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H 0x48 -+#define AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF GENMASK(20, 16) -+#define AIROHA_PCS_ANA_JCPLL_SPARE_L GENMASK(15, 8) -+#define AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO BIT(5) -+#define AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS 0x50 -+#define AIROHA_PCS_ANA_TXPLL_LPF_BC GENMASK(28, 24) -+#define AIROHA_PCS_ANA_TXPLL_LPF_BR GENMASK(20, 16) -+#define AIROHA_PCS_ANA_TXPLL_CHP_IOFST GENMASK(13, 8) -+#define AIROHA_PCS_ANA_TXPLL_CHP_IBIAS GENMASK(5, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP 0x54 -+#define AIROHA_PCS_ANA_TXPLL_KBAND_OPTION BIT(24) -+#define AIROHA_PCS_ANA_TXPLL_LPF_BWC GENMASK(20, 16) -+#define AIROHA_PCS_ANA_TXPLL_LPF_BWR GENMASK(12, 8) -+#define AIROHA_PCS_ANA_TXPLL_LPF_BP GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE 0x58 -+#define AIROHA_PCS_ANA_TXPLL_KBAND_KF GENMASK(25, 24) -+#define AIROHA_PCS_ANA_TXPLL_KBAND_KFC GENMASK(17, 16) -+#define AIROHA_PCS_ANA_TXPLL_KBAND_DIV GENMASK(10, 8) -+#define AIROHA_PCS_ANA_TXPLL_KBAND_CODE GENMASK(7, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS 0x5c -+#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE GENMASK(17, 16) -+#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2 0x0 -+#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_3 0x1 -+#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_4 0x2 -+#define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 0x3 -+#define AIROHA_PCS_ANA_TXPLL_POSTDIV_EN BIT(8) -+#define AIROHA_PCS_ANA_TXPLL_KBAND_KS GENMASK(1, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL 0x64 -+#define AIROHA_PCS_ANA_TXPLL_PLL_RSTB BIT(24) -+#define AIROHA_PCS_ANA_TXPLL_RST_DLY GENMASK(18, 16) -+#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV GENMASK(9, 8) -+#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1 0x0 -+#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_2 0x1 -+#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_3 0x2 -+#define AIROHA_PCS_ANA_TXPLL_REFIN_DIV_4 0x3 -+#define AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL BIT(0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN 0x68 -+#define AIROHA_PCS_ANA_TXPLL_SDM_MODE GENMASK(25, 24) -+#define AIROHA_PCS_ANA_TXPLL_SDM_IFM BIT(16) -+#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS GENMASK(9, 8) -+#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23 0x0 -+#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_21 0x1 -+#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_19 0x2 -+#define AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_15 0x3 -+#define AIROHA_PCS_ANA_TXPLL_SDM_DI_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD 0x6c -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN BIT(24) -+#define AIROHA_PCS_ANA_TXPLL_SDM_HREN BIT(16) -+#define AIROHA_PCS_ANA_TXPLL_SDM_OUT BIT(8) -+#define AIROHA_PCS_ANA_TXPLL_SDM_ORD GENMASK(1, 0) -+#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_INT 0x0 -+#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_1SDM 0x1 -+#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_2SDM 0x2 -+#define AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM 0x3 -+#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN 0x70 -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF GENMASK(12, 8) -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN GENMASK(2, 0) -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2 0x0 -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_2_5 0x1 -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_3 0x2 -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4 0x3 -+#define AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_6 0x4 -+#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN 0x74 -+#define AIROHA_PCS_ANA_TXPLL_VCO_CFIX GENMASK(25, 24) -+#define AIROHA_PCS_ANA_TXPLL_VCODIV GENMASK(17, 16) -+#define AIROHA_PCS_ANA_TXPLL_VCODIV_1 0x0 -+#define AIROHA_PCS_ANA_TXPLL_VCODIV_2 0x1 -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW GENMASK(10, 8) -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5 0x0 -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_1 0x1 -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_2 0x2 -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_4 0x3 -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_8 0x4 -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_16 0x6 -+#define AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN 0x78 -+#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L GENMASK(29, 27) -+#define AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H GENMASK(26, 24) -+#define AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR GENMASK(18, 16) -+#define AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR GENMASK(10, 8) -+#define AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN 0x7c -+#define AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN BIT(16) -+#define AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI BIT(8) -+#define AIROHA_PCS_ANA_TXPLL_SSC_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1 0x80 -+#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA GENMASK(31, 16) -+#define AIROHA_PCS_ANA_TXPLL_SSC_DELTA1 GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD 0x84 -+#define AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT GENMASK(25, 24) -+#define AIROHA_PCS_ANA_TXPLL_LDO_OUT GENMASK(17, 16) -+#define AIROHA_PCS_ANA_TXPLL_SSC_PERIOD GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF 0x94 -+#define AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_TX_CKLDO_EN 0xc4 -+#define AIROHA_PCS_ANA_TX_DMEDGEGEN_EN BIT(24) -+#define AIROHA_PCS_ANA_TX_CKLDO_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL 0xcc -+#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE BIT(24) -+#define AIROHA_PCS_ANA_RX_PHY_CK_SEL BIT(16) -+#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_PR 0x0 -+#define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_DES 0x1 -+#define AIROHA_PCS_ANA_PXP_RX_REV_0 0xd4 -+#define AIROHA_PCS_ANA_RX_REV_1 GENMASK(31, 16) -+#define AIROHA_PCS_ANA_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) -+#define AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24) -+#define AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) -+#define AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK GENMASK(19, 18) -+#define AIROHA_PCS_ANA_REV_1_FECUR_PWDB BIT(16) -+#define AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV 0xd8 -+#define AIROHA_PCS_ANA_RX_TDC_CK_SEL BIT(24) -+#define AIROHA_PCS_ANA_RX_PHYCK_RSTB BIT(16) -+#define AIROHA_PCS_ANA_RX_PHYCK_SEL GENMASK(9, 8) -+#define AIROHA_PCS_ANA_RX_PHYCK_DIV GENMASK(7, 0) -+#define AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV 0xdc -+#define AIROHA_PCS_ANA_CDR_PD_EDGE_DIS BIT(8) -+#define AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV BIT(0) -+#define AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO 0xe8 -+#define AIROHA_PCS_ANA_CDR_LPF_TOP_LIM GENMASK(26, 8) -+#define AIROHA_PCS_ANA_CDR_LPF_RATIO GENMASK(1, 0) -+#define AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE 0xf4 -+#define AIROHA_PCS_ANA_CDR_PR_INJ_FORCE_OFF BIT(24) -+#define AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC 0xf8 -+#define AIROHA_PCS_ANA_CDR_PR_KBAND_DIV GENMASK(26, 24) -+#define AIROHA_PCS_ANA_CDR_PR_BETA_SEL GENMASK(19, 16) -+#define AIROHA_PCS_ANA_CDR_PR_VCOADC_OS GENMASK(11, 8) -+#define AIROHA_PCS_ANA_CDR_PR_BETA_DAC GENMASK(6, 0) -+#define AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL 0xfc -+#define AIROHA_PCS_ANA_CDR_PR_FBKSEL GENMASK(25, 24) -+#define AIROHA_PCS_ANA_CDR_PR_DAC_BAND GENMASK(20, 16) -+#define AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL GENMASK(10, 8) -+#define AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN 0x10c -+#define AIROHA_PCS_ANA_RX_DAC_MON GENMASK(28, 24) -+#define AIROHA_PCS_ANA_CDR_PR_CAP_EN BIT(19) -+#define AIROHA_PCS_ANA_CDR_BUF_IN_SR GENMASK(18, 16) -+#define AIROHA_PCS_ANA_CDR_PR_XFICK_EN BIT(2) -+#define AIROHA_PCS_ANA_CDR_PR_MONPI_EN BIT(1) -+#define AIROHA_PCS_ANA_CDR_PR_MONPR_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_RX_DAC_RANGE 0x110 -+#define AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL GENMASK(25, 24) -+#define AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH 0x114 -+#define AIROHA_PCS_ANA_RX_FE_50OHMS_SEL GENMASK(25, 24) -+#define AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL GENMASK(20, 16) -+#define AIROHA_PCS_ANA_RX_SIGDET_PEAK GENMASK(9, 8) -+#define AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN 0x118 -+#define AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN BIT(24) -+#define AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN BIT(16) -+#define AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN BIT(8) -+#define AIROHA_PCS_ANA_RX_FE_EQ_HZEN BIT(0) -+#define AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB 0x11c -+#define AIROHA_PCS_ANA_RX_FE_VCM_GEN_PWDB BIT(0) -+#define AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW 0x120 -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE GENMASK(17, 8) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS BIT(0) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS BIT(1) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS BIT(2) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS BIT(3) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS BIT(4) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS BIT(5) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS BIT(6) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS BIT(7) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH BIT(8) -+#define AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS BIT(9) -+#define AIROHA_PCS_ANA_PXP_AEQ_CFORCE 0x13c -+#define AIROHA_PCS_ANA_AEQ_OFORCE GENMASK(19, 8) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_SAOS BIT(0) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP1 BIT(1) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP2 BIT(2) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP3 BIT(3) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP4 BIT(4) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP5 BIT(5) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP6 BIT(6) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_DFETP7 BIT(7) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_VGA BIT(8) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_CTLE BIT(9) -+#define AIROHA_PCS_ANA_AEQ_OFORCE_ATT BIT(10) -+#define AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB 0x144 -+#define AIROHA_PCS_ANA_RX_DAC_D0_BYPASS_AEQ BIT(24) -+#define AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ 0x148 -+#define AIROHA_PCS_ANA_RX_DAC_EYE_BYPASS_AEQ BIT(24) -+#define AIROHA_PCS_ANA_RX_DAC_E1_BYPASS_AEQ BIT(16) -+#define AIROHA_PCS_ANA_RX_DAC_E0_BYPASS_AEQ BIT(8) -+#define AIROHA_PCS_ANA_RX_DAC_D1_BYPASS_AEQ BIT(0) -+ -+/* PMA_PHYA 2L */ -+#define AIROHA_PCS_ANA_PXP_2L_CMN_EN 0x0 -+#define AIROHA_PCS_ANA_2L_CMN_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN 0x4 -+#define AIROHA_PCS_ANA_2L_JCPLL_CHP_IOFST GENMASK(29, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_CHP_IBIAS GENMASK(21, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_LPF_SHCK_EN BIT(8) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR 0x8 -+#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BWR GENMASK(28, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BP GENMASK(20, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BC GENMASK(12, 8) -+#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BR GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC 0xc -+#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_DIV GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_CODE GENMASK(23, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_OPTION BIT(8) -+#define AIROHA_PCS_ANA_2L_JCPLL_LPF_BWC GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC 0x10 -+#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_KS GENMASK(17, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_KF GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_JCPLL_KBAND_KFC GENMASK(1, 0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE 0x14 -+#define AIROHA_PCS_ANA_2L_JCPLL_POSTDIV_D5 BIT(24) -+#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE GENMASK(1, 0) -+#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_2 0x0 -+#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_3 0x1 -+#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_4 0x2 -+#define AIROHA_PCS_ANA_2L_JCPLL_MMD_PREDIV_MODE_1 0x3 -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY 0x1c -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS GENMASK(25, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_23 0x0 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_21 0x1 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_19 0x2 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_LS_2_15 0x3 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_DI_EN BIT(16) -+#define AIROHA_PCS_ANA_2L_JCPLL_PLL_RSTB BIT(8) -+#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY GENMASK(2, 0) -+#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_20_25 0x1 -+#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_40_50 0x2 -+#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_80_100 0x3 -+#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_150_200 0x4 -+#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_300_400 0x5 -+#define AIROHA_PCS_ANA_2L_JCPLL_RST_DLY_600_800 0x6 -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM 0x20 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_OUT BIT(24) -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD GENMASK(17, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_INT 0x0 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_1SDM 0x1 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_2SDM 0x2 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_ORD_3SDM 0x3 -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_MODE GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_IFM BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN 0x24 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_VREF GENMASK(28, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN GENMASK(18, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_2 0x0 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_4 0x1 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_6 0x2 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_8 0x3 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_GAIN_10 0x4 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_AMP_EN BIT(8) -+#define AIROHA_PCS_ANA_2L_JCPLL_SDM_HREN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN 0x28 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_0_5 0x0 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_1 0x1 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_2 0x2 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_4 0x3 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_8 0x4 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW_16 0x6 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_EN BIT(16) -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_LPF_BW GENMASK(26, 24) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV 0x2c -+#define AIROHA_PCS_ANA_2L_JCPLL_VCO_SCAPWR GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_VCO_HALFLSB_EN BIT(16) -+#define AIROHA_PCS_ANA_2L_JCPLL_VCO_CFIX GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_JCPLL_VCODIV GENMASK(1, 0) -+#define AIROHA_PCS_ANA_2L_JCPLL_VCODIV_1 0x0 -+#define AIROHA_PCS_ANA_2L_JCPLL_VCODIV_2 0x1 -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR 0x30 -+#define AIROHA_PCS_ANA_2L_JCPLL_VCO_VCOVAR_BIAS_L GENMASK(18, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_VCO_VCOVAR_BIAS_H GENMASK(10, 8) -+#define AIROHA_PCS_ANA_2L_JCPLL_VCO_TCLVAR GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN 0x38 -+#define AIROHA_PCS_ANA_2L_JCPLL_SSC_TRI_EN BIT(16) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1 0x3c -+#define AIROHA_PCS_ANA_2L_JCPLL_SSC_DELTA GENMASK(31, 16) -+#define AIROHA_PCS_ANA_2L_JCPLL_SSC_DELTA1 GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_PERIOD 0x40 -+#define AIROHA_PCS_ANA_2L_JCPLL_SSC_PERIOD GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_VTP_EN 0x4c -+#define AIROHA_PCS_ANA_2L_JCPLL_SPARE_L GENMASK(31, 24) -+#define AIROHA_PCS_ANA_2L_JCPLL_SPARE_L_LDO FIELD_PREP_CONST(AIROHA_PCS_ANA_JCPLL_SPARE_L, BIT(5)) -+#define AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_KBAND_VREF 0x50 -+#define AIROHA_PCS_ANA_2L_JCPLL_TCL_KBAND_VREF GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_750M_SYS_CK_EN 0x54 -+#define AIROHA_PCS_ANA_2L_TXPLL_CHP_IBIAS GENMASK(29, 24) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST 0x58 -+#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BP GENMASK(28, 24) -+#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BC GENMASK(20, 16) -+#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BR GENMASK(12, 8) -+#define AIROHA_PCS_ANA_2L_TXPLL_CHP_IOFST GENMASK(5, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR 0x5c -+#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_CODE GENMASK(31, 24) -+#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_OPTION BIT(16) -+#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BWC GENMASK(12, 8) -+#define AIROHA_PCS_ANA_2L_TXPLL_LPF_BWR GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV 0x60 -+#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_KS GENMASK(25, 24) -+#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_KF GENMASK(17, 16) -+#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_KFC GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_TXPLL_KBAND_DIV GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN 0x64 -+#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_2 0x0 -+#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_3 0x1 -+#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_4 0x2 -+#define AIROHA_PCS_ANA_2L_TXPLL_MMD_PREDIV_MODE_1 0x3 -+#define AIROHA_PCS_ANA_2L_TXPLL_POSTDIV_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_PHY_CK2_EN 0x68 -+#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_INTERNAL BIT(24) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV 0x6c -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_EN BIT(24) -+#define AIROHA_PCS_ANA_2L_TXPLL_PLL_RSTB BIT(16) -+#define AIROHA_PCS_ANA_2L_TXPLL_RST_DLY GENMASK(10, 8) -+#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV GENMASK(1, 0) -+#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_1 0x0 -+#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_2 0x1 -+#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_3 0x2 -+#define AIROHA_PCS_ANA_2L_TXPLL_REFIN_DIV_4 0x3 -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS 0x70 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD GENMASK(25, 24) -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_INT 0x0 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_1SDM 0x1 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_2SDM 0x2 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_ORD_3SDM 0x3 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_MODE GENMASK(17, 16) -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_IFM BIT(8) -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS GENMASK(1, 0) -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_23 0x0 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_21 0x1 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_19 0x2 -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_DI_LS_2_15 0x3 -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT 0x74 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_2 0x0 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_2_5 0x1 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_3 0x2 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_4 0x3 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_GAIN_6 0x4 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_EN BIT(16) -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_HREN BIT(8) -+#define AIROHA_PCS_ANA_2L_TXPLL_SDM_OUT BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF 0x78 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_EN BIT(24) -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_AMP_VREF GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW 0x7c -+#define AIROHA_PCS_ANA_2L_TXPLL_VCO_HALFLSB_EN BIT(24) -+#define AIROHA_PCS_ANA_2L_TXPLL_VCO_CFIX GENMASK(17, 16) -+#define AIROHA_PCS_ANA_2L_TXPLL_VCODIV GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_TXPLL_VCODIV_1 0x0 -+#define AIROHA_PCS_ANA_2L_TXPLL_VCODIV_2 0x1 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW GENMASK(2, 0) -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_0_5 0x0 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_1 0x1 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_2 0x2 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_4 0x3 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_8 0x4 -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_LPF_BW_16 0x6 -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR 0x80 -+#define AIROHA_PCS_ANA_2L_TXPLL_VCO_VCOVAR_BIAS_L GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_TXPLL_VCO_VCOVAR_BIAS_H GENMASK(18, 16) -+#define AIROHA_PCS_ANA_2L_TXPLL_VCO_TCLVAR GENMASK(10, 8) -+#define AIROHA_PCS_ANA_2L_TXPLL_VCO_SCAPWR GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN 0x84 -+#define AIROHA_PCS_ANA_2L_TXPLL_SSC_TRI_EN BIT(16) -+#define AIROHA_PCS_ANA_2L_TXPLL_SSC_PHASE_INI BIT(8) -+#define AIROHA_PCS_ANA_2L_TXPLL_SSC_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1 0x88 -+#define AIROHA_PCS_ANA_2L_TXPLL_SSC_DELTA GENMASK(31, 16) -+#define AIROHA_PCS_ANA_2L_TXPLL_SSC_DELTA1 GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD 0x8c -+#define AIROHA_PCS_ANA_2L_TXPLL_LDO_VCO_OUT GENMASK(25, 24) -+#define AIROHA_PCS_ANA_2L_TXPLL_LDO_OUT GENMASK(17, 16) -+#define AIROHA_PCS_ANA_2L_TXPLL_SSC_PERIOD GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_KBAND_VREF 0x9c -+#define AIROHA_PCS_ANA_2L_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_TX0_CKLDO_EN 0xcc -+#define AIROHA_PCS_ANA_2L_TX0_DMEDGEGEN_EN BIT(24) -+#define AIROHA_PCS_ANA_2L_TX0_CKLDO_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_TX1_CKLDO_EN 0xe8 -+#define AIROHA_PCS_ANA_2L_TX1_DMEDGEGEN_EN BIT(24) -+#define AIROHA_PCS_ANA_2L_TX1_CKLDO_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_BUSBIT_SEL 0xf4 -+#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FORCE BIT(24) -+#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL BIT(16) -+#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_PR 0x0 -+#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_DES 0x1 -+#define AIROHA_PCS_ANA_PXP_2L_RX0_REV_0 0xfc -+#define AIROHA_PCS_ANA_2L_RX0_REV_1 GENMASK(31, 16) -+#define AIROHA_PCS_ANA_2L_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) -+#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) -+#define AIROHA_PCS_ANA_2L_REV_1_SIGDET_ILEAK GENMASK(19, 18) -+#define AIROHA_PCS_ANA_2L_REV_1_FECUR_PWDB BIT(16) -+#define AIROHA_PCS_ANA_2L_RX0_REV_0 GENMASK(15, 0) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF2_BIAS_TYPE GENMASK(13, 12) -+#define AIROHA_PCS_ANA_2L_REV_0_OSCAL_FE_MODE_SET_SEL BIT(11) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_TRAINING BIT(10) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_TRAINING GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_NORMAL BIT(6) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_NORMAL GENMASK(5, 4) -+#define AIROHA_PCS_ANA_2L_REV_0_VOS_PNINV GENMASK(3, 2) -+#define AIROHA_PCS_ANA_2L_REV_0_PLEYEBD4 BIT(1) -+#define AIROHA_PCS_ANA_2L_REV_0_PLEYE_XOR_MON_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV 0x100 -+#define AIROHA_PCS_ANA_2L_RX0_TDC_CK_SEL BIT(24) -+#define AIROHA_PCS_ANA_2L_RX0_PHYCK_RSTB BIT(16) -+#define AIROHA_PCS_ANA_2L_RX0_PHYCK_SEL GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_RX0_PHYCK_DIV GENMASK(7, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_PD_PICAL_CKD8_INV 0x104 -+#define AIROHA_PCS_ANA_2L_CDR0_PD_EDGE_DIS BIT(8) -+#define AIROHA_PCS_ANA_2L_CDR0_PD_PICAL_CKD8_INV BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_LPF_RATIO 0x110 -+#define AIROHA_PCS_ANA_2L_CDR0_LPF_TOP_LIM GENMASK(26, 8) -+#define AIROHA_PCS_ANA_2L_CDR0_LPF_RATIO GENMASK(1, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_INJ_MODE 0x11c -+#define AIROHA_PCS_ANA_2L_CDR0_PR_INJ_FORCE_OFF BIT(24) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC 0x120 -+#define AIROHA_PCS_ANA_2L_CDR0_PR_KBAND_DIV GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_BETA_SEL GENMASK(19, 16) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_VCOADC_OS GENMASK(11, 8) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_BETA_DAC GENMASK(6, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL 0x124 -+#define AIROHA_PCS_ANA_2L_CDR0_PR_FBKSEL GENMASK(25, 24) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_DAC_BAND GENMASK(20, 16) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_VREG_CKBUF_VAL GENMASK(10, 8) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_VREG_IBAND_VAL GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_COR_HBW_EN 0x130 -+#define AIROHA_PCS_ANA_2L_CDR0_PR_MONPR_EN BIT(24) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_MONPI_EN 0x134 -+#define AIROHA_PCS_ANA_2L_CDR0_PR_XFICK_EN BIT(8) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_MONPI_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BUF_IN_SR 0x138 -+#define AIROHA_PCS_ANA_2L_CDR0_PR_CAP_EN BIT(8) -+#define AIROHA_PCS_ANA_2L_CDR0_PR_BUF_IN_SR GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_DAC_MON 0x13c -+#define AIROHA_PCS_ANA_2L_RX0_DAC_MON GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_DCTEST_EN 0x140 -+#define AIROHA_PCS_ANA_2L_RX0_SIGDET_PEAK GENMASK(25, 24) -+#define AIROHA_PCS_ANA_2L_RX0_SIGDET_LPF_CTRL GENMASK(9, 8) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL 0x144 -+#define AIROHA_PCS_ANA_2L_RX0_FE_VB_EQ1_EN BIT(24) -+#define AIROHA_PCS_ANA_2L_RX0_FE_EQ_HZEN BIT(16) -+#define AIROHA_PCS_ANA_2L_RX0_SIGDET_VTH_SEL GENMASK(4, 0) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN 0x148 -+#define AIROHA_PCS_ANA_2L_RX0_FE_VCM_GEN_PWDB BIT(16) -+#define AIROHA_PCS_ANA_2L_RX0_FE_VB_EQ3_EN BIT(8) -+#define AIROHA_PCS_ANA_2L_RX0_FE_VB_EQ2_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_OSCAL_FORCE 0x150 -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE GENMASK(17, 8) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA2VOS BIT(0) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA2IOS BIT(1) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA1VOS BIT(2) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_VGA1IOS BIT(3) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE2VOS BIT(4) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE2IOS BIT(5) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE1VOS BIT(6) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_CTLE1IOS BIT(7) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_LVSH BIT(8) -+#define AIROHA_PCS_ANA_2L_RX0_OSCAL_FORCE_COMPOS BIT(9) -+#define AIROHA_PCS_ANA_PXP_2L_AEQ0_CFORCE 0x170 -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE GENMASK(19, 8) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_SAOS BIT(0) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP1 BIT(1) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP2 BIT(2) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP3 BIT(3) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP4 BIT(4) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP5 BIT(5) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP6 BIT(6) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_DFETP7 BIT(7) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_VGA BIT(8) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_CTLE BIT(9) -+#define AIROHA_PCS_ANA_2L_AEQ0_OFORCE_ATT BIT(10) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ 0x17c -+#define AIROHA_PCS_ANA_2L_RX0_DAC_E1_BYPASS_AEQ BIT(24) -+#define AIROHA_PCS_ANA_2L_RX0_DAC_E0_BYPASS_AEQ BIT(16) -+#define AIROHA_PCS_ANA_2L_RX0_DAC_D1_BYPASS_AEQ BIT(8) -+#define AIROHA_PCS_ANA_2L_RX0_DAC_D0_BYPASS_AEQ BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_RX0_DAC_EYE_BYPASS_AEQ 0x180 -+#define AIROHA_PCS_ANA_2L_RX0_DAC_EYE_BYPASS_AEQ BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_FE_PEACKING_CTRL_LSB 0x234 -+#define AIROHA_PCS_ANA_2L_RX1_DAC_D0_BYPASS_AEQ BIT(24) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_BUSBIT_SEL 0x1ac -+#define AIROHA_PCS_ANA_2L_RX1_PHY_CK_SEL_FORCE BIT(24) -+#define AIROHA_PCS_ANA_2L_RX1_PHY_CK_SEL BIT(16) -+#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_PR 0x0 -+#define AIROHA_PCS_ANA_2L_RX0_PHY_CK_SEL_FROM_DES 0x1 -+#define AIROHA_PCS_ANA_PXP_2L_RX1_REV_0 0x1b4 -+#define AIROHA_PCS_ANA_2L_RX1_REV_1 GENMASK(31, 16) -+#define AIROHA_PCS_ANA_2L_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) -+#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF1_BIAS_CTRL GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) -+#define AIROHA_PCS_ANA_2L_REV_1_SIGDET_ILEAK GENMASK(19, 18) -+#define AIROHA_PCS_ANA_2L_REV_1_FECUR_PWDB BIT(16) -+#define AIROHA_PCS_ANA_2L_RX1_REV_0 GENMASK(15, 0) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF2_BIAS_TYPE GENMASK(13, 12) -+#define AIROHA_PCS_ANA_2L_REV_0_OSCAL_FE_MODE_SET_SEL BIT(11) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_TRAINING BIT(10) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_TRAINING GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_EQ_GAIN_MODE_NORMAL BIT(6) -+#define AIROHA_PCS_ANA_2L_REV_0_FE_BUF_GAIN_MODE_NORMAL GENMASK(5, 4) -+#define AIROHA_PCS_ANA_2L_REV_0_VOS_PNINV GENMASK(3, 2) -+#define AIROHA_PCS_ANA_2L_REV_0_PLEYEBD4 BIT(1) -+#define AIROHA_PCS_ANA_2L_REV_0_PLEYE_XOR_MON_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV 0x1b8 -+#define AIROHA_PCS_ANA_2L_RX1_TDC_CK_SEL BIT(24) -+#define AIROHA_PCS_ANA_2L_RX1_PHYCK_RSTB BIT(16) -+#define AIROHA_PCS_ANA_2L_RX1_PHYCK_SEL GENMASK(9, 8) -+#define AIROHA_PCS_ANA_2L_RX1_PHYCK_DIV GENMASK(7, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_PD_PICAL_CKD8_INV 0x1bc -+#define AIROHA_PCS_ANA_2L_CDR1_PD_EDGE_DIS BIT(8) -+#define AIROHA_PCS_ANA_2L_CDR1_PD_PICAL_CKD8_INV BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_LPF_RATIO 0x1c8 -+#define AIROHA_PCS_ANA_2L_CDR1_LPF_TOP_LIM GENMASK(26, 8) -+#define AIROHA_PCS_ANA_2L_CDR1_LPF_RATIO GENMASK(1, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_INJ_MODE 0x1d4 -+#define AIROHA_PCS_ANA_2L_CDR1_PR_INJ_FORCE_OFF BIT(24) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC 0x1d8 -+#define AIROHA_PCS_ANA_2L_CDR1_PR_KBAND_DIV GENMASK(26, 24) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_BETA_SEL GENMASK(19, 16) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_VCOADC_OS GENMASK(11, 8) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_BETA_DAC GENMASK(6, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL 0x1dc -+#define AIROHA_PCS_ANA_2L_CDR1_PR_FBKSEL GENMASK(25, 24) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_DAC_BAND GENMASK(20, 16) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_VREG_CKBUF_VAL GENMASK(10, 8) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_VREG_IBAND_VAL GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_COR_HBW_EN 0x1e8 -+#define AIROHA_PCS_ANA_2L_CDR1_PR_MONPR_EN BIT(24) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_MONPI_EN 0x1ec -+#define AIROHA_PCS_ANA_2L_CDR1_PR_XFICK_EN BIT(8) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_MONPI_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR 0x1f0 -+#define AIROHA_PCS_ANA_2L_RX1_DAC_MON GENMASK(20, 16) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_CAP_EN BIT(8) -+#define AIROHA_PCS_ANA_2L_CDR1_PR_BUF_IN_SR GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_DAC_RANGE_EYE 0x1f4 -+#define AIROHA_PCS_ANA_2L_RX1_SIGDET_LPF_CTRL GENMASK(25, 24) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_SIGDET_NOVTH 0x1f8 -+#define AIROHA_PCS_ANA_2L_RX1_SIGDET_VTH_SEL GENMASK(20, 16) -+#define AIROHA_PCS_ANA_2L_RX1_SIGDET_PEAK GENMASK(9, 8) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_FE_50OHMS_SEL 0x1fc -+#define AIROHA_PCS_ANA_2L_RX1_FE_EQ_HZEN BIT(24) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN 0x200 -+#define AIROHA_PCS_ANA_2L_RX1_FE_VCM_GEN_PWDB BIT(24) -+#define AIROHA_PCS_ANA_2L_RX1_FE_VB_EQ3_EN BIT(16) -+#define AIROHA_PCS_ANA_2L_RX1_FE_VB_EQ2_EN BIT(8) -+#define AIROHA_PCS_ANA_2L_RX1_FE_VB_EQ1_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_OSCAL_WATCH_WNDW 0x208 -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE GENMASK(25, 16) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA2VOS BIT(0) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA2IOS BIT(1) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA1VOS BIT(2) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_VGA1IOS BIT(3) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE2VOS BIT(4) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE2IOS BIT(5) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE1VOS BIT(6) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_CTLE1IOS BIT(7) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_LVSH BIT(8) -+#define AIROHA_PCS_ANA_2L_RX1_OSCAL_FORCE_COMPOS BIT(9) -+#define AIROHA_PCS_ANA_PXP_2L_AEQ1_CFORCE 0x228 -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE GENMASK(27, 16) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_SAOS BIT(0) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP1 BIT(1) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP2 BIT(2) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP3 BIT(3) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP4 BIT(4) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP5 BIT(5) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP6 BIT(6) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_DFETP7 BIT(7) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_VGA BIT(8) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_CTLE BIT(9) -+#define AIROHA_PCS_ANA_2L_AEQ1_OFORCE_ATT BIT(10) -+#define AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ 0x238 -+#define AIROHA_PCS_ANA_2L_RX1_DAC_EYE_BYPASS_AEQ BIT(24) -+#define AIROHA_PCS_ANA_2L_RX1_DAC_E1_BYPASS_AEQ BIT(16) -+#define AIROHA_PCS_ANA_2L_RX1_DAC_E0_BYPASS_AEQ BIT(8) -+#define AIROHA_PCS_ANA_2L_RX1_DAC_D1_BYPASS_AEQ BIT(0) -+ -+/* PMA_PHYD */ -+#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0 0x0 -+#define AIROHA_PCS_PMA_SW_LCPLL_EN BIT(24) -+#define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1 0x4 -+#define AIROHA_PCS_PMA_LCPLL_MAN_PWDB BIT(0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2 0x88 -+#define AIROHA_PCS_PMA_DATA_SHIFT BIT(8) -+#define AIROHA_PCS_PMA_EYECNT_FAST BIT(0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0 0x8c -+#define AIROHA_PCS_PMA_RX_OS_START GENMASK(23, 8) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT GENMASK(2, 0) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_05 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x0) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x1) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x2) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x3) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_0_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x4) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_1_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x5) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_3_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x6) -+#define AIROHA_PCS_PMA_OSC_SPEED_OPT_6_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_OSC_SPEED_OPT, 0x7) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1 0x90 -+#define AIROHA_PCS_PMA_RX_PICAL_END GENMASK(31, 16) -+#define AIROHA_PCS_PMA_RX_PICAL_START GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2 0x94 -+#define AIROHA_PCS_PMA_RX_PDOS_END GENMASK(31, 16) -+#define AIROHA_PCS_PMA_RX_PDOS_START GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3 0x98 -+#define AIROHA_PCS_PMA_RX_FEOS_END GENMASK(31, 16) -+#define AIROHA_PCS_PMA_RX_FEOS_START GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4 0x9c -+#define AIROHA_PCS_PMA_RX_SDCAL_END GENMASK(31, 16) -+#define AIROHA_PCS_PMA_RX_SDCAL_START GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5 0x100 -+#define AIROHA_PCS_PMA_RX_RDY GENMASK(31, 16) -+#define AIROHA_PCS_PMA_RX_BLWC_RDY_EN GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6 0x104 -+#define AIROHA_PCS_PMA_RX_OS_END GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1 0x10c -+#define AIROHA_PCS_PMA_DISB_RX_RDY BIT(24) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1 0x114 -+#define AIROHA_PCS_PMA_FORCE_RX_RDY BIT(24) -+#define AIROHA_PCS_PMA_PHY_EQ_CTRL_2 0x120 -+#define AIROHA_PCS_PMA_EQ_DEBUG_SEL GENMASK(17, 16) -+#define AIROHA_PCS_PMA_FOM_NUM_ORDER GENMASK(12, 8) -+#define AIROHA_PCS_PMA_A_SEL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_1 0x14c -+#define AIROHA_PCS_PMA_UNLOCK_CYCLECNT GENMASK(31, 16) -+#define AIROHA_PCS_PMA_LOCK_CYCLECNT GENMASK(15, 0) -+#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_2 0x150 -+#define AIROHA_PCS_PMA_LOCK_TARGET_END GENMASK(31, 16) -+#define AIROHA_PCS_PMA_LOCK_TARGET_BEG GENMASK(15, 0) -+#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_3 0x154 -+#define AIROHA_PCS_PMA_UNLOCK_TARGET_END GENMASK(31, 16) -+#define AIROHA_PCS_PMA_UNLOCK_TARGET_BEG GENMASK(15, 0) -+#define AIROHA_PCS_PMA_SS_RX_FREQ_DET_4 0x158 -+#define AIROHA_PCS_PMA_LOCK_UNLOCKTH GENMASK(15, 12) -+#define AIROHA_PCS_PMA_LOCK_LOCKTH GENMASK(11, 8) -+#define AIROHA_PCS_PMA_FREQLOCK_DET_EN GENMASK(2, 0) -+#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x0) -+#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x1) -+#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_WAIT FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x2) -+#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x3) -+#define AIROHA_PCS_PMA_FREQLOCK_DET_EN_RX_STATE FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x7) -+#define AIROHA_PCS_PMA_SS_RX_SIGDET_1 0x16c -+#define AIROHA_PCS_PMA_SIGDET_EN BIT(0) -+#define AIROHA_PCS_PMA_RX_FLL_1 0x174 -+#define AIROHA_PCS_PMA_LPATH_IDAC GENMASK(10, 0) -+#define AIROHA_PCS_PMA_RX_FLL_2 0x178 -+#define AIROHA_PCS_PMA_CK_RATE GENMASK(18, 16) -+#define AIROHA_PCS_PMA_CK_RATE_20 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x0) -+#define AIROHA_PCS_PMA_CK_RATE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x1) -+#define AIROHA_PCS_PMA_CK_RATE_5 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x2) -+#define AIROHA_PCS_PMA_RX_FLL_5 0x184 -+#define AIROHA_PCS_PMA_FLL_IDAC_MIN GENMASK(26, 16) -+#define AIROHA_PCS_PMA_FLL_IDAC_MAX GENMASK(10, 0) -+#define AIROHA_PCS_PMA_RX_FLL_B 0x19c -+#define AIROHA_PCS_PMA_LOAD_EN BIT(0) -+#define AIROHA_PCS_PMA_RX_RESET_1 0x208 -+#define AIROHA_PCS_PMA_SIGDET_RST_B BIT(8) -+#define AIROHA_PCS_PMA_TX_RST_B 0x260 -+#define AIROHA_PCS_PMA_TXCALIB_RST_B BIT(8) -+#define AIROHA_PCS_PMA_TX_TOP_RST_B BIT(0) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_4 0x320 -+#define AIROHA_PCS_PMA_DISB_BLWC_OFFSET BIT(24) -+#define AIROHA_PCS_PMA_RX_FORCE_MODE_9 0x330 -+#define AIROHA_PCS_PMA_FORCE_FBCK_LOCK BIT(0) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_8 0x33c -+#define AIROHA_PCS_PMA_DISB_FBCK_LOCK BIT(0) -+#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0 0x34c -+#define AIROHA_PCS_PMA_XPON_CDR_PD_PWDB BIT(24) -+#define AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB BIT(16) -+#define AIROHA_PCS_PMA_XPON_CDR_PW_PWDB BIT(8) -+#define AIROHA_PCS_PMA_XPON_RX_FE_PWDB BIT(0) -+#define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1 0x350 -+#define AIROHA_PCS_PMA_RX_SIDGET_PWDB BIT(0) -+#define AIROHA_PCS_PMA_DIG_RESERVE_0 0x360 -+#define AIROHA_PCS_TRIGGER_RX_SIDGET_SCAN GENMASK(17, 16) -+#define AIROHA_PCS_PMA_XPON_RX_RESERVED_1 0x374 -+#define AIROHA_PCS_PMA_XPON_RX_RATE_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_DIG_RO_RESERVE_2 0x380 -+#define AIROHA_PCS_RX_SIGDET BIT(8) -+#define AIROHA_PCS_PMA_RX_SYS_EN_SEL_0 0x38c -+#define AIROHA_PCS_PMA_RX_SYS_EN_SEL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_0 0x390 -+#define AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT GENMASK(15, 0) -+#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_1 0x394 -+#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_END GENMASK(31, 16) -+#define AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG GENMASK(15, 0) -+#define AIROHA_PCS_PMA_PLL_TDC_FREQDET_3 0x39c -+#define AIROHA_PCS_PMA_PLL_LOCK_LOCKTH GENMASK(11, 8) -+#define AIROHA_PCS_PMA_ADD_XPON_MODE_1 0x414 -+#define AIROHA_PCS_PMA_XFI_RX_MODE GENMASK(11, 9) -+#define AIROHA_PCS_PMA_XFI_RX_MODE_10G3 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x0) -+#define AIROHA_PCS_PMA_XFI_RX_MODE_5G15 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x1) -+#define AIROHA_PCS_PMA_XFI_RX_MODE_6G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x2) -+#define AIROHA_PCS_PMA_XFI_RX_MODE_2G57 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x3) -+#define AIROHA_PCS_PMA_XFI_RX_MODE_3G12 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x4) -+#define AIROHA_PCS_PMA_XFI_RX_MODE_1G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x5) -+#define AIROHA_PCS_PMA_R2T_MODE BIT(8) -+#define AIROHA_PCS_PMA_XFI_TX_MODE GENMASK(5, 3) -+#define AIROHA_PCS_PMA_XFI_TX_MODE_10G3 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x0) -+#define AIROHA_PCS_PMA_XFI_TX_MODE_5G15 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x1) -+#define AIROHA_PCS_PMA_XFI_TX_MODE_6G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x2) -+#define AIROHA_PCS_PMA_XFI_TX_MODE_2G57 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x3) -+#define AIROHA_PCS_PMA_XFI_TX_MODE_3G12 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x4) -+#define AIROHA_PCS_PMA_XFI_TX_MODE_1G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x5) -+#define AIROHA_PCS_PMA_SW_RST_SET 0x460 -+#define AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N BIT(11) -+#define AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N BIT(10) -+#define AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N BIT(9) -+#define AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N BIT(8) -+#define AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N BIT(7) -+#define AIROHA_PCS_PMA_SW_TX_FIFO_RST_N BIT(6) -+#define AIROHA_PCS_PMA_SW_REF_RST_N BIT(5) -+#define AIROHA_PCS_PMA_SW_ALLPCS_RST_N BIT(4) -+#define AIROHA_PCS_PMA_SW_PMA_RST_N BIT(3) -+#define AIROHA_PCS_PMA_SW_TX_RST_N BIT(2) -+#define AIROHA_PCS_PMA_SW_RX_RST_N BIT(1) -+#define AIROHA_PCS_PMA_SW_RX_FIFO_RST_N BIT(0) -+#define AIROHA_PCS_PMA_XPON_INT_EN_3 0x474 -+#define AIROHA_PCS_PMA_RX_SIGDET_INT_EN BIT(16) -+#define AIROHA_PCS_PMA_XPON_INT_STA_3 0x47c -+#define AIROHA_PCS_PMA_RX_SIGDET_INT BIT(16) -+#define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c -+#define AIROHA_PCS_PMA_DISB_LEQ BIT(0) -+#define AIROHA_PCS_PMA_RX_FREQDET 0x530 -+#define AIROHA_PCS_PMA_FL_OUT GENMASK(31, 16) -+#define AIROHA_PCS_PMA_FBCK_LOCK BIT(0) -+#define AIROHA_PCS_PMA_XPON_TX_RATE_CTRL 0x580 -+#define AIROHA_PCS_PMA_PON_TX_RATE_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN 0x768 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL GENMASK(19, 16) -+#define AIROHA_PCS_PMA_PXP_AEQ_SPEED 0x76c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_OSR_SEL GENMASK(17, 16) -+#define AIROHA_PCS_PMA_PXP_TX_FIR_C0B 0x778 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 GENMASK(20, 16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B GENMASK(5, 0) -+#define AIROHA_PCS_PMA_PXP_TX_TERM_SEL 0x77c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR GENMASK(19, 16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL GENMASK(2, 0) -+#define AIROHA_PCS_PMA_PXP_TX_FIR_C1 0x780 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 GENMASK(20, 16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1 GENMASK(5, 0) -+#define AIROHA_PCS_PMA_PXP_TX_RATE_CTRL 0x784 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_PXP_CDR_PR_IDAC 0x794 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW BIT(24) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC BIT(16) -+#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC GENMASK(10, 0) -+#define AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR GENMASK(10, 8) -+#define AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW 0x798 -+#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW GENMASK(30, 0) -+#define AIROHA_PCS_PMA_PXP_RX_FE_VOS 0x79c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_FE_VOS GENMASK(5, 0) -+#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW 0x800 -+#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW GENMASK(30, 0) -+#define AIROHA_PCS_PMA_PXP_AEQ_BYPASS 0x80c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON BIT(16) -+#define AIROHA_PCS_PMA_PXP_AEQ_RSTB 0x814 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL BIT(16) -+#define AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA 0x818 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA BIT(0) -+#define AIROHA_PCS_PMA_PXP_CDR_PD_PWDB 0x81c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB BIT(0) -+#define AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN 0x820 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN BIT(0) -+#define AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB 0x824 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB BIT(0) -+#define AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN 0x828 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN BIT(0) -+#define AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B 0x84c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B BIT(0) -+#define AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN 0x854 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN BIT(0) -+#define AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN 0x874 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL BIT(16) -+#define AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL 0x88c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_PXP_RX_FE_PWDB 0x894 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB BIT(0) -+#define AIROHA_PCS_PMA_DIG_RESERVE_29 0x910 -+#define AIROHA_PCS_PMA_2L_TX_RATE_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_2L_RX_RATE_CTRL GENMASK(5, 4) -+ -+#define AIROHA_PCS_MAX_CALIBRATION_TRY 50 -+#define AIROHA_PCS_MAX_NUM_RSTS 2 -+ -+enum xfi_port_type { -+ AIROHA_PCS_ETH, -+ AIROHA_PCS_PON, -+ AIROHA_PCS_USB, -+ AIROHA_PCS_PCIE, -+}; -+ -+struct airoha_pcs_maps { -+ struct regmap *pcs_mac; -+ struct regmap *hsgmii_an; -+ struct regmap *hsgmii_pcs; -+ struct regmap *hsgmii_rate_adp; -+ struct regmap *multi_sgmii; -+ struct regmap *usxgmii_pcs; -+}; -+ -+struct airoha_pcs_priv { -+ struct device *dev; -+ const struct airoha_pcs_match_data *data; -+ phy_interface_t interface; -+ -+ struct airoha_pcs_port *ports; -+ -+ struct regmap *scu; -+ -+ struct airoha_pcs_maps maps[2]; -+ -+ struct regmap *pcs_pma[2]; -+ struct regmap *pcs_ana; -+ struct regmap_field **pcs_ana_fields[2]; -+ -+ struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS]; -+ -+ struct phy *phy; -+ -+ bool manual_rx_calib; -+}; -+ -+struct airoha_pcs_port { -+ struct airoha_pcs_priv *priv; -+ int index; -+ -+ struct phylink_pcs pcs; -+}; -+ -+struct airoha_pcs_match_data { -+ int num_port; -+ enum xfi_port_type port_type; -+ -+ int (*alloc_regmap_fields)(struct airoha_pcs_priv *priv); -+ int (*bringup)(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface); -+ void (*link_up)(struct airoha_pcs_priv *priv, int index); -+ int (*rxlock_workaround)(struct airoha_pcs_priv *priv, int index); -+}; -+ -+#define to_airoha_pcs_port(n) container_of(n, struct airoha_pcs_port, pcs) -+ -+#ifdef CONFIG_PCS_AIROHA_AN7581 -+int an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv); -+int an7581_pcs_pcie_alloc_regmap_fields(struct airoha_pcs_priv *priv); -+int an7581_pcs_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface); -+int an7581_pcs_usb_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface); -+ -+void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv, int index); -+int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv, int index); -+#else -+static inline int an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int an7581_pcs_pcie_alloc_regmap_fields(struct airoha_pcs_priv *priv) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int an7581_pcs_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int an7581_pcs_usb_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv, -+ int index) -+{ -+} -+ -+static inline int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ return 0; -+} -+#endif ---- /dev/null -+++ b/drivers/net/pcs/airoha/pcs-an7581.c -@@ -0,0 +1,2093 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Christian Marangi -+ */ -+#include -+#include -+#include -+ -+#include "pcs-airoha.h" -+ -+#include -+ -+enum { -+ AN7581_PCS_CMN_EN, -+ -+ AN7581_PCS_JCPLL_SPARE_L, -+ AN7581_PCS_JCPLL_RST_DLY, -+ AN7581_PCS_JCPLL_PLL_RSTB, -+ AN7581_PCS_JCPLL_SDM_DI_LS, -+ AN7581_PCS_JCPLL_SDM_DI_EN, -+ -+ AN7581_PCS_JCPLL_SDM_OUT, -+ AN7581_PCS_JCPLL_SDM_ORD, -+ AN7581_PCS_JCPLL_SDM_MODE, -+ AN7581_PCS_JCPLL_SDM_IFM, -+ AN7581_PCS_JCPLL_SDM_HREN, -+ -+ AN7581_PCS_JCPLL_CHP_IOFST, -+ AN7581_PCS_JCPLL_CHP_IBIAS, -+ AN7581_PCS_JCPLL_LPF_SHCK_EN, -+ -+ AN7581_PCS_JCPLL_LPF_BWR, -+ AN7581_PCS_JCPLL_LPF_BP, -+ AN7581_PCS_JCPLL_LPF_BC, -+ AN7581_PCS_JCPLL_LPF_BR, -+ AN7581_PCS_JCPLL_LPF_BWC, -+ -+ AN7581_PCS_JCPLL_VCO_SCAPWR, -+ AN7581_PCS_JCPLL_VCO_HALFLSB_EN, -+ AN7581_PCS_JCPLL_VCO_CFIX, -+ AN7581_PCS_JCPLL_VCODIV, -+ AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L, -+ AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H, -+ AN7581_PCS_JCPLL_VCO_TCLVAR, -+ -+ AN7581_PCS_JCPLL_POSTDIV_D5, -+ AN7581_PCS_JCPLL_MMD_PREDIV_MODE, -+ -+ AN7581_PCS_JCPLL_KBAND_KS, -+ AN7581_PCS_JCPLL_KBAND_KF, -+ AN7581_PCS_JCPLL_KBAND_KFC, -+ AN7581_PCS_JCPLL_KBAND_DIV, -+ AN7581_PCS_JCPLL_KBAND_CODE, -+ AN7581_PCS_JCPLL_KBAND_OPTION, -+ -+ AN7581_PCS_JCPLL_TCL_AMP_VREF, -+ AN7581_PCS_JCPLL_TCL_AMP_GAIN, -+ AN7581_PCS_JCPLL_TCL_AMP_EN, -+ -+ AN7581_PCS_JCPLL_TCL_LPF_BW, -+ AN7581_PCS_JCPLL_TCL_LPF_EN, -+ -+ AN7581_PCS_JCPLL_SSC_DELTA, -+ AN7581_PCS_JCPLL_SSC_DELTA1, -+ AN7581_PCS_JCPLL_SSC_PERIOD, -+ AN7581_PCS_JCPLL_SSC_TRI_EN, -+ AN7581_PCS_JCPLL_SSC_EN, -+ AN7581_PCS_JCPLL_SSC_PHASE_INI, -+ AN7581_PCS_JCPLL_TCL_KBAND_VREF, -+ -+ AN7581_PCS_TXPLL_LDO_VCO_OUT, -+ AN7581_PCS_TXPLL_LDO_OUT, -+ AN7581_PCS_TXPLL_PLL_RSTB, -+ AN7581_PCS_TXPLL_RST_DLY, -+ AN7581_PCS_TXPLL_REFIN_DIV, -+ AN7581_PCS_TXPLL_REFIN_INTERNAL, -+ AN7581_PCS_TXPLL_SDM_MODE, -+ AN7581_PCS_TXPLL_SDM_IFM, -+ AN7581_PCS_TXPLL_SDM_DI_LS, -+ AN7581_PCS_TXPLL_SDM_DI_EN, -+ AN7581_PCS_TXPLL_SDM_HREN, -+ AN7581_PCS_TXPLL_SDM_ORD, -+ AN7581_PCS_TXPLL_SDM_OUT, -+ AN7581_PCS_TXPLL_SSC_DELTA1, -+ AN7581_PCS_TXPLL_SSC_DELTA, -+ AN7581_PCS_TXPLL_SSC_TRI_EN, -+ AN7581_PCS_TXPLL_SSC_PHASE_INI, -+ AN7581_PCS_TXPLL_SSC_EN, -+ AN7581_PCS_TXPLL_SSC_PERIOD, -+ AN7581_PCS_TXPLL_LPF_BC, -+ AN7581_PCS_TXPLL_LPF_BR, -+ AN7581_PCS_TXPLL_LPF_BP, -+ AN7581_PCS_TXPLL_LPF_BWC, -+ AN7581_PCS_TXPLL_LPF_BWR, -+ AN7581_PCS_TXPLL_CHP_IOFST, -+ AN7581_PCS_TXPLL_CHP_IBIAS, -+ AN7581_PCS_TXPLL_VCO_CFIX, -+ AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L, -+ AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H, -+ AN7581_PCS_TXPLL_VCO_TCLVAR, -+ AN7581_PCS_TXPLL_VCO_SCAPWR, -+ AN7581_PCS_TXPLL_VCO_HALFLSB_EN, -+ AN7581_PCS_TXPLL_KBAND_CODE, -+ AN7581_PCS_TXPLL_KBAND_OPTION, -+ AN7581_PCS_TXPLL_KBAND_KS, -+ AN7581_PCS_TXPLL_KBAND_KF, -+ AN7581_PCS_TXPLL_KBAND_KFC, -+ AN7581_PCS_TXPLL_KBAND_DIV, -+ AN7581_PCS_TXPLL_MMD_PREDIV_MODE, -+ AN7581_PCS_TXPLL_POSTDIV_EN, -+ AN7581_PCS_TXPLL_VCODIV, -+ AN7581_PCS_TXPLL_TCL_KBAND_VREF, -+ AN7581_PCS_TXPLL_TCL_AMP_GAIN, -+ AN7581_PCS_TXPLL_TCL_AMP_VREF, -+ AN7581_PCS_TXPLL_TCL_LPF_BW, -+ AN7581_PCS_TXPLL_TCL_LPF_EN, -+ AN7581_PCS_TXPLL_TCL_AMP_EN, -+ -+ AN7581_PCS_TX_DMEDGEGEN_EN, -+ AN7581_PCS_TX_CKLDO_EN, -+ -+ AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ, -+ AN7581_PCS_RX_DAC_E1_BYPASS_AEQ, -+ AN7581_PCS_RX_DAC_E0_BYPASS_AEQ, -+ AN7581_PCS_RX_DAC_D1_BYPASS_AEQ, -+ AN7581_PCS_RX_DAC_D0_BYPASS_AEQ, -+ AN7581_PCS_RX_FE_VCM_GEN_PWDB, -+ AN7581_PCS_RX_OSCAL_FORCE, -+ AN7581_PCS_RX_DAC_MON, -+ AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL, -+ AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL, -+ AN7581_PCS_RX_REV_1_SIGDET_ILEAK, -+ AN7581_PCS_RX_FE_VB_EQ3_EN, -+ AN7581_PCS_RX_FE_VB_EQ2_EN, -+ AN7581_PCS_RX_FE_VB_EQ1_EN, -+ AN7581_PCS_RX_FE_EQ_HZEN, -+ AN7581_PCS_RX_SIGDET_VTH_SEL, -+ AN7581_PCS_RX_SIGDET_PEAK, -+ AN7581_PCS_RX_SIGDET_LPF_CTRL, -+ AN7581_PCS_RX_TDC_CK_SEL, -+ AN7581_PCS_RX_PHYCK_RSTB, -+ AN7581_PCS_RX_PHYCK_SEL, -+ AN7581_PCS_RX_PHYCK_DIV, -+ AN7581_PCS_RX_PHY_CK_SEL_FORCE, -+ AN7581_PCS_RX_PHY_CK_SEL, -+ -+ AN7581_PCS_AEQ_OFORCE, -+ -+ AN7581_PCS_CDR_PD_EDGE_DIS, -+ AN7581_PCS_CDR_PD_PICAL_CKD8_INV, -+ -+ AN7581_PCS_CDR_PR_XFICK_EN, -+ AN7581_PCS_CDR_PR_MONPI_EN, -+ AN7581_PCS_CDR_PR_MONPR_EN, -+ AN7581_PCS_CDR_PR_KBAND_DIV, -+ AN7581_PCS_CDR_PR_BETA_SEL, -+ AN7581_PCS_CDR_PR_VCOADC_OS, -+ AN7581_PCS_CDR_PR_BETA_DAC, -+ AN7581_PCS_CDR_PR_FBKSEL, -+ AN7581_PCS_CDR_PR_DAC_BAND, -+ AN7581_PCS_CDR_PR_VREG_CKBUF_VAL, -+ AN7581_PCS_CDR_PR_VREG_IBAND_VAL, -+ AN7581_PCS_CDR_PR_CAP_EN, -+ AN7581_PCS_CDR_PR_INJ_FORCE_OFF, -+ -+ AN7581_PCS_CDR_BUF_IN_SR, -+ -+ AN7581_PCS_CDR_LPF_TOP_LIM, -+ AN7581_PCS_CDR_LPF_RATIO, -+ -+ AN7581_PCS_FIELDS_MAX, -+}; -+ -+static const struct reg_field an7581_pcs_fields[AN7581_PCS_FIELDS_MAX] = { -+ [AN7581_PCS_CMN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CMN_EN, 0, 0), -+ -+ [AN7581_PCS_JCPLL_SPARE_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, 8, 15), -+ -+ [AN7581_PCS_JCPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 0, 2), -+ [AN7581_PCS_JCPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 8, 8), -+ [AN7581_PCS_JCPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 16, 16), -+ [AN7581_PCS_JCPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_RST_DLY, 24, 25), -+ -+ [AN7581_PCS_JCPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 24, 24), -+ [AN7581_PCS_JCPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 16, 17), -+ [AN7581_PCS_JCPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 8, 9), -+ [AN7581_PCS_JCPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_IFM, 0, 0), -+ [AN7581_PCS_JCPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 0, 0), -+ -+ [AN7581_PCS_JCPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA, 16, 31), -+ [AN7581_PCS_JCPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_DELTA, 0, 15), -+ [AN7581_PCS_JCPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN, 8, 23), -+ [AN7581_PCS_JCPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SSC_TRI_EN, 0, 0), -+ [AN7581_PCS_JCPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 17, 17), -+ [AN7581_PCS_JCPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 16, 16), -+ [AN7581_PCS_JCPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, 16, 20), -+ -+ [AN7581_PCS_JCPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, 24, 29), -+ [AN7581_PCS_JCPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, 16, 21), -+ [AN7581_PCS_JCPLL_LPF_SHCK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN, 8, 8), -+ -+ [AN7581_PCS_JCPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 24, 28), -+ [AN7581_PCS_JCPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 16, 20), -+ [AN7581_PCS_JCPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 8, 12), -+ [AN7581_PCS_JCPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BR, 0, 4), -+ [AN7581_PCS_JCPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 0, 4), -+ -+ [AN7581_PCS_JCPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 24, 26), -+ [AN7581_PCS_JCPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 16, 16), -+ [AN7581_PCS_JCPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 8, 9), -+ [AN7581_PCS_JCPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCODIV, 0, 1), -+ [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 8, 10), -+ [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 3, 5), -+ [AN7581_PCS_JCPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_VCO_TCLVAR, 0, 2), -+ -+ [AN7581_PCS_JCPLL_POSTDIV_D5] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE, 24, 24), -+ [AN7581_PCS_JCPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_MMD_PREDIV_MODE, 0, 1), -+ -+ [AN7581_PCS_JCPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, 16, 17), -+ [AN7581_PCS_JCPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, 8, 9), -+ [AN7581_PCS_JCPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_KBAND_KFC, 0, 1), -+ [AN7581_PCS_JCPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 24, 26), -+ [AN7581_PCS_JCPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 16, 23), -+ [AN7581_PCS_JCPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_LPF_BWC, 8, 8), -+ -+ [AN7581_PCS_JCPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 24, 28), -+ [AN7581_PCS_JCPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 16, 18), -+ [AN7581_PCS_JCPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_SDM_HREN, 8, 8), -+ -+ [AN7581_PCS_JCPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN, 24, 26), -+ [AN7581_PCS_JCPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_JCPLL_TCL_CMP_EN, 16, 16), -+ -+ [AN7581_PCS_TXPLL_LDO_VCO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, 24, 25), -+ [AN7581_PCS_TXPLL_LDO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, 16, 17), -+ [AN7581_PCS_TXPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 24, 24), -+ [AN7581_PCS_TXPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 16, 18), -+ [AN7581_PCS_TXPLL_REFIN_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 8, 9), -+ [AN7581_PCS_TXPLL_REFIN_INTERNAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, 0, 0), -+ [AN7581_PCS_TXPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 24, 25), -+ [AN7581_PCS_TXPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 16, 16), -+ [AN7581_PCS_TXPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 8, 9), -+ [AN7581_PCS_TXPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, 0, 0), -+ [AN7581_PCS_TXPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 16, 16), -+ [AN7581_PCS_TXPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 8, 8), -+ [AN7581_PCS_TXPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 0, 1), -+ [AN7581_PCS_TXPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, 16, 31), -+ [AN7581_PCS_TXPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, 0, 15), -+ [AN7581_PCS_TXPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, 16, 16), -+ [AN7581_PCS_TXPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, 8, 8), -+ [AN7581_PCS_TXPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, 0, 0), -+ [AN7581_PCS_TXPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, 0, 15), -+ [AN7581_PCS_TXPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 24, 28), -+ [AN7581_PCS_TXPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 16, 20), -+ [AN7581_PCS_TXPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 8, 13), -+ [AN7581_PCS_TXPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, 0, 5), -+ [AN7581_PCS_TXPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 16, 20), -+ [AN7581_PCS_TXPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 8, 12), -+ [AN7581_PCS_TXPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 0, 4), -+ [AN7581_PCS_TXPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 24, 25), -+ [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 27, 29), -+ [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 24, 26), -+ [AN7581_PCS_TXPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 16, 18), -+ [AN7581_PCS_TXPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 8, 10), -+ [AN7581_PCS_TXPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, 0, 0), -+ [AN7581_PCS_TXPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 0, 7), -+ [AN7581_PCS_TXPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, 24, 24), -+ [AN7581_PCS_TXPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, 0, 1), -+ [AN7581_PCS_TXPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 24, 25), -+ [AN7581_PCS_TXPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 16, 17), -+ [AN7581_PCS_TXPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, 8, 10), -+ [AN7581_PCS_TXPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, 16, 17), -+ [AN7581_PCS_TXPLL_POSTDIV_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, 8, 8), -+ [AN7581_PCS_TXPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 16, 17), -+ [AN7581_PCS_TXPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, 0, 4), -+ [AN7581_PCS_TXPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, 0, 2), -+ [AN7581_PCS_TXPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, 8, 12), -+ [AN7581_PCS_TXPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 8, 10), -+ [AN7581_PCS_TXPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 0, 0), -+ [AN7581_PCS_TXPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, 24, 24), -+ -+ [AN7581_PCS_TX_DMEDGEGEN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, 24, 24), -+ [AN7581_PCS_TX_CKLDO_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, 0, 0), -+ -+ [AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 24, 24), -+ [AN7581_PCS_RX_DAC_E1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 16, 16), -+ [AN7581_PCS_RX_DAC_E0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 8, 8), -+ [AN7581_PCS_RX_DAC_D1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_D1_BYPASS_AEQ, 0, 0), -+ [AN7581_PCS_RX_DAC_D0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_PEAKING_CTRL_MSB, 24, 24), -+ [AN7581_PCS_RX_FE_VCM_GEN_PWDB] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB, 0, 0), -+ -+ [AN7581_PCS_AEQ_OFORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_AEQ_CFORCE, 8, 19), -+ [AN7581_PCS_RX_OSCAL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW, 8, 17), -+ -+ [AN7581_PCS_CDR_PD_EDGE_DIS] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, 8, 8), -+ [AN7581_PCS_CDR_PD_PICAL_CKD8_INV] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, 0, 0), -+ -+ [AN7581_PCS_RX_DAC_MON] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 24, 28), -+ [AN7581_PCS_CDR_PR_XFICK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 2, 2), -+ [AN7581_PCS_CDR_PR_MONPI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 1, 1), -+ [AN7581_PCS_CDR_PR_MONPR_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 0, 0), -+ -+ [AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_REV_0, 24, 26), -+ [AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_REV_0, 20, 22), -+ [AN7581_PCS_RX_REV_1_SIGDET_ILEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_REV_0, 18, 19), -+ -+ [AN7581_PCS_CDR_LPF_TOP_LIM] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, 8, 26), -+ [AN7581_PCS_CDR_LPF_RATIO] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, 0, 1), -+ -+ [AN7581_PCS_CDR_PR_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 24, 26), -+ [AN7581_PCS_CDR_PR_BETA_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 16, 19), -+ [AN7581_PCS_CDR_PR_VCOADC_OS] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 8, 11), -+ [AN7581_PCS_CDR_PR_BETA_DAC] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, 0, 6), -+ [AN7581_PCS_CDR_PR_FBKSEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 24, 25), -+ [AN7581_PCS_CDR_PR_DAC_BAND] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 16, 20), -+ [AN7581_PCS_CDR_PR_VREG_CKBUF_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 8, 10), -+ [AN7581_PCS_CDR_PR_VREG_IBAND_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, 0, 2), -+ -+ [AN7581_PCS_RX_FE_VB_EQ3_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 24, 24), -+ [AN7581_PCS_RX_FE_VB_EQ2_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 16, 16), -+ [AN7581_PCS_RX_FE_VB_EQ1_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 8, 8), -+ [AN7581_PCS_RX_FE_EQ_HZEN] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, 0, 0), -+ -+ [AN7581_PCS_CDR_PR_CAP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 19, 19), -+ [AN7581_PCS_CDR_BUF_IN_SR] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, 16, 18), -+ -+ [AN7581_PCS_RX_SIGDET_VTH_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, 16, 20), -+ [AN7581_PCS_RX_SIGDET_PEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, 8, 9), -+ [AN7581_PCS_RX_SIGDET_LPF_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, 24, 25), -+ -+ [AN7581_PCS_RX_TDC_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 24, 24), -+ [AN7581_PCS_RX_PHYCK_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 16, 16), -+ [AN7581_PCS_RX_PHYCK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 8, 9), -+ [AN7581_PCS_RX_PHYCK_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, 0, 7), -+ [AN7581_PCS_RX_PHY_CK_SEL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, 24, 24), -+ [AN7581_PCS_RX_PHY_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, 16, 16), -+ -+ [AN7581_PCS_CDR_PR_INJ_FORCE_OFF] = REG_FIELD(AIROHA_PCS_ANA_PXP_CDR_PR_INJ_MODE, 24, 24), -+}; -+ -+static const struct reg_field an7581_pcs_pcie0_fields[AN7581_PCS_FIELDS_MAX] = { -+ [AN7581_PCS_CMN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CMN_EN, 0, 0), -+ -+ [AN7581_PCS_JCPLL_SPARE_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_VTP_EN, 24, 31), -+ -+ [AN7581_PCS_JCPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 0, 2), -+ [AN7581_PCS_JCPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 8, 8), -+ [AN7581_PCS_JCPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 16, 16), -+ [AN7581_PCS_JCPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 24, 25), -+ -+ [AN7581_PCS_JCPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 24, 24), -+ [AN7581_PCS_JCPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 16, 17), -+ [AN7581_PCS_JCPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 8, 9), -+ [AN7581_PCS_JCPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 0, 0), -+ [AN7581_PCS_JCPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 0, 0), -+ -+ [AN7581_PCS_JCPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 24, 29), -+ [AN7581_PCS_JCPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 16, 21), -+ [AN7581_PCS_JCPLL_LPF_SHCK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 8, 8), -+ -+ [AN7581_PCS_JCPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 24, 28), -+ [AN7581_PCS_JCPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 16, 20), -+ [AN7581_PCS_JCPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 8, 12), -+ [AN7581_PCS_JCPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 0, 4), -+ [AN7581_PCS_JCPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 0, 4), -+ -+ [AN7581_PCS_JCPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 24, 26), -+ [AN7581_PCS_JCPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 16, 16), -+ [AN7581_PCS_JCPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 8, 9), -+ [AN7581_PCS_JCPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 0, 1), -+ [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 16, 18), -+ [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 8, 10), -+ [AN7581_PCS_JCPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 0, 2), -+ -+ [AN7581_PCS_JCPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 16, 31), -+ [AN7581_PCS_JCPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 0, 15), -+ [AN7581_PCS_JCPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_PERIOD, 0, 15), -+ [AN7581_PCS_JCPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 16, 16), -+ [AN7581_PCS_JCPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 8, 8), -+ [AN7581_PCS_JCPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 0, 0), -+ [AN7581_PCS_JCPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_KBAND_VREF, 0, 4), -+ -+ [AN7581_PCS_JCPLL_POSTDIV_D5] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 24, 24), -+ [AN7581_PCS_JCPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 0, 1), -+ -+ [AN7581_PCS_JCPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 16, 17), -+ [AN7581_PCS_JCPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 8, 9), -+ [AN7581_PCS_JCPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 0, 1), -+ [AN7581_PCS_JCPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 24, 26), -+ [AN7581_PCS_JCPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 16, 23), -+ [AN7581_PCS_JCPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 8, 8), -+ -+ [AN7581_PCS_JCPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 24, 28), -+ [AN7581_PCS_JCPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 16, 18), -+ [AN7581_PCS_JCPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 8, 8), -+ -+ [AN7581_PCS_JCPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 24, 26), -+ [AN7581_PCS_JCPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 16, 16), -+ -+ [AN7581_PCS_TXPLL_LDO_VCO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 24, 25), -+ [AN7581_PCS_TXPLL_LDO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 16, 17), -+ [AN7581_PCS_TXPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 16, 16), -+ [AN7581_PCS_TXPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 8, 10), -+ [AN7581_PCS_TXPLL_REFIN_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 0, 1), -+ [AN7581_PCS_TXPLL_REFIN_INTERNAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_PHY_CK2_EN, 24, 24), -+ [AN7581_PCS_TXPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 16, 17), -+ [AN7581_PCS_TXPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 8, 8), -+ [AN7581_PCS_TXPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 0, 1), -+ [AN7581_PCS_TXPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 24, 24), -+ [AN7581_PCS_TXPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 8, 8), -+ [AN7581_PCS_TXPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 0, 0), -+ [AN7581_PCS_TXPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 24, 25), -+ [AN7581_PCS_TXPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 16, 31), -+ [AN7581_PCS_TXPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 0, 15), -+ [AN7581_PCS_TXPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 16, 16), -+ [AN7581_PCS_TXPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 8, 8), -+ [AN7581_PCS_TXPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 0, 0), -+ [AN7581_PCS_TXPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 0, 15), -+ [AN7581_PCS_TXPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 16, 20), -+ [AN7581_PCS_TXPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 8, 12), -+ [AN7581_PCS_TXPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 0, 5), -+ [AN7581_PCS_TXPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_750M_SYS_CK_EN, 24, 29), -+ [AN7581_PCS_TXPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 8, 12), -+ [AN7581_PCS_TXPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 0, 4), -+ [AN7581_PCS_TXPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 24, 28), -+ [AN7581_PCS_TXPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 16, 17), -+ [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 24, 26), -+ [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 16, 18), -+ [AN7581_PCS_TXPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 8, 10), -+ [AN7581_PCS_TXPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 0, 2), -+ [AN7581_PCS_TXPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 24, 24), -+ [AN7581_PCS_TXPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 24, 31), -+ [AN7581_PCS_TXPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 16, 16), -+ [AN7581_PCS_TXPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 24, 25), -+ [AN7581_PCS_TXPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 16, 17), -+ [AN7581_PCS_TXPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 8, 9), -+ [AN7581_PCS_TXPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 0, 2), -+ [AN7581_PCS_TXPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 8, 9), -+ [AN7581_PCS_TXPLL_POSTDIV_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 0, 0), -+ [AN7581_PCS_TXPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 8, 9), -+ [AN7581_PCS_TXPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_KBAND_VREF, 0, 4), -+ [AN7581_PCS_TXPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 24, 26), -+ [AN7581_PCS_TXPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 0, 4), -+ [AN7581_PCS_TXPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 0, 2), -+ [AN7581_PCS_TXPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 0, 0), -+ [AN7581_PCS_TXPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 24, 24), -+ -+ [AN7581_PCS_TX_DMEDGEGEN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX0_CKLDO_EN, 24, 24), -+ [AN7581_PCS_TX_CKLDO_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX0_CKLDO_EN, 0, 0), -+ -+ [AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_EYE_BYPASS_AEQ, 0, 0), -+ [AN7581_PCS_RX_DAC_E1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 24, 24), -+ [AN7581_PCS_RX_DAC_E0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 16, 16), -+ [AN7581_PCS_RX_DAC_D1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 8, 8), -+ [AN7581_PCS_RX_DAC_D0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_D0_BYPASS_AEQ, 0, 0), -+ [AN7581_PCS_RX_FE_VCM_GEN_PWDB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN, 16, 16), -+ -+ [AN7581_PCS_AEQ_OFORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_AEQ0_CFORCE, 8, 19), -+ [AN7581_PCS_RX_OSCAL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_OSCAL_FORCE, 8, 17), -+ -+ [AN7581_PCS_CDR_PD_EDGE_DIS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PD_PICAL_CKD8_INV, 8, 8), -+ [AN7581_PCS_CDR_PD_PICAL_CKD8_INV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PD_PICAL_CKD8_INV, 0, 0), -+ -+ [AN7581_PCS_RX_DAC_MON] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_DAC_MON, 0, 4), -+ [AN7581_PCS_CDR_PR_XFICK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_MONPI_EN, 8, 8), -+ [AN7581_PCS_CDR_PR_MONPI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_MONPI_EN, 0, 0), -+ [AN7581_PCS_CDR_PR_MONPR_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_COR_HBW_EN, 24, 24), -+ -+ [AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_REV_0, 24, 26), -+ [AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_REV_0, 20, 22), -+ [AN7581_PCS_RX_REV_1_SIGDET_ILEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_REV_0, 18, 19), -+ -+ [AN7581_PCS_CDR_LPF_TOP_LIM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_LPF_RATIO, 8, 26), -+ [AN7581_PCS_CDR_LPF_RATIO] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_LPF_RATIO, 0, 1), -+ -+ [AN7581_PCS_CDR_PR_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 24, 26), -+ [AN7581_PCS_CDR_PR_BETA_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 16, 19), -+ [AN7581_PCS_CDR_PR_VCOADC_OS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 8, 11), -+ [AN7581_PCS_CDR_PR_BETA_DAC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BETA_DAC, 0, 6), -+ [AN7581_PCS_CDR_PR_FBKSEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 24, 25), -+ [AN7581_PCS_CDR_PR_DAC_BAND] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 16, 20), -+ [AN7581_PCS_CDR_PR_VREG_CKBUF_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 8, 10), -+ [AN7581_PCS_CDR_PR_VREG_IBAND_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_VREG_IBAND_VAL, 0, 2), -+ -+ [AN7581_PCS_RX_FE_VB_EQ3_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN, 8, 8), -+ [AN7581_PCS_RX_FE_VB_EQ2_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_FE_VB_EQ2_EN, 0, 0), -+ [AN7581_PCS_RX_FE_VB_EQ1_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL, 24, 24), -+ [AN7581_PCS_RX_FE_EQ_HZEN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL, 16, 16), -+ -+ [AN7581_PCS_CDR_PR_CAP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BUF_IN_SR, 8, 8), -+ [AN7581_PCS_CDR_BUF_IN_SR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_BUF_IN_SR, 0, 2), -+ -+ [AN7581_PCS_RX_SIGDET_VTH_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_VTH_SEL, 0, 4), -+ [AN7581_PCS_RX_SIGDET_PEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_DCTEST_EN, 24, 25), -+ [AN7581_PCS_RX_SIGDET_LPF_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_SIGDET_DCTEST_EN, 8, 9), -+ -+ [AN7581_PCS_RX_TDC_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 24, 24), -+ [AN7581_PCS_RX_PHYCK_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 16, 16), -+ [AN7581_PCS_RX_PHYCK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 8, 9), -+ [AN7581_PCS_RX_PHYCK_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_PHYCK_DIV, 0, 7), -+ [AN7581_PCS_RX_PHY_CK_SEL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_BUSBIT_SEL, 24, 24), -+ [AN7581_PCS_RX_PHY_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX0_BUSBIT_SEL, 16, 16), -+ -+ [AN7581_PCS_CDR_PR_INJ_FORCE_OFF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR0_PR_INJ_MODE, 24, 24), -+}; -+ -+static const struct reg_field an7581_pcs_pcie1_fields[AN7581_PCS_FIELDS_MAX] = { -+ [AN7581_PCS_CMN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CMN_EN, 0, 0), -+ -+ [AN7581_PCS_JCPLL_SPARE_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_VTP_EN, 24, 31), -+ -+ [AN7581_PCS_JCPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 0, 2), -+ [AN7581_PCS_JCPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 8, 8), -+ [AN7581_PCS_JCPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 16, 16), -+ [AN7581_PCS_JCPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_RST_DLY, 24, 25), -+ -+ [AN7581_PCS_JCPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 24, 24), -+ [AN7581_PCS_JCPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 16, 17), -+ [AN7581_PCS_JCPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 8, 9), -+ [AN7581_PCS_JCPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_IFM, 0, 0), -+ [AN7581_PCS_JCPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 0, 0), -+ -+ [AN7581_PCS_JCPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 24, 29), -+ [AN7581_PCS_JCPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 16, 21), -+ [AN7581_PCS_JCPLL_LPF_SHCK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_IB_EXT_EN, 8, 8), -+ -+ [AN7581_PCS_JCPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 24, 28), -+ [AN7581_PCS_JCPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 16, 20), -+ [AN7581_PCS_JCPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 8, 12), -+ [AN7581_PCS_JCPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BR, 0, 4), -+ [AN7581_PCS_JCPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 0, 4), -+ -+ [AN7581_PCS_JCPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 24, 26), -+ [AN7581_PCS_JCPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 16, 16), -+ [AN7581_PCS_JCPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 8, 9), -+ [AN7581_PCS_JCPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCODIV, 0, 1), -+ [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 16, 18), -+ [AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 8, 10), -+ [AN7581_PCS_JCPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_VCO_TCLVAR, 0, 2), -+ -+ [AN7581_PCS_JCPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 16, 31), -+ [AN7581_PCS_JCPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_DELTA1, 0, 15), -+ [AN7581_PCS_JCPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_PERIOD, 0, 15), -+ [AN7581_PCS_JCPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 16, 16), -+ [AN7581_PCS_JCPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 8, 8), -+ [AN7581_PCS_JCPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SSC_EN, 0, 0), -+ [AN7581_PCS_JCPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_KBAND_VREF, 0, 4), -+ -+ [AN7581_PCS_JCPLL_POSTDIV_D5] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 24, 24), -+ [AN7581_PCS_JCPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_MMD_PREDIV_MODE, 0, 1), -+ -+ [AN7581_PCS_JCPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 16, 17), -+ [AN7581_PCS_JCPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 8, 9), -+ [AN7581_PCS_JCPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_KBAND_KFC, 0, 1), -+ [AN7581_PCS_JCPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 24, 26), -+ [AN7581_PCS_JCPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 16, 23), -+ [AN7581_PCS_JCPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_LPF_BWC, 8, 8), -+ -+ [AN7581_PCS_JCPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 24, 28), -+ [AN7581_PCS_JCPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 16, 18), -+ [AN7581_PCS_JCPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_SDM_HREN, 8, 8), -+ -+ [AN7581_PCS_JCPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 24, 26), -+ [AN7581_PCS_JCPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_JCPLL_TCL_CMP_EN, 16, 16), -+ -+ [AN7581_PCS_TXPLL_LDO_VCO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 24, 25), -+ [AN7581_PCS_TXPLL_LDO_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 16, 17), -+ [AN7581_PCS_TXPLL_PLL_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 16, 16), -+ [AN7581_PCS_TXPLL_RST_DLY] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 8, 10), -+ [AN7581_PCS_TXPLL_REFIN_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 0, 1), -+ [AN7581_PCS_TXPLL_REFIN_INTERNAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_PHY_CK2_EN, 24, 24), -+ [AN7581_PCS_TXPLL_SDM_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 16, 17), -+ [AN7581_PCS_TXPLL_SDM_IFM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 8, 8), -+ [AN7581_PCS_TXPLL_SDM_DI_LS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 0, 1), -+ [AN7581_PCS_TXPLL_SDM_DI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_REFIN_DIV, 24, 24), -+ [AN7581_PCS_TXPLL_SDM_HREN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 8, 8), -+ [AN7581_PCS_TXPLL_SDM_OUT] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 0, 0), -+ [AN7581_PCS_TXPLL_SDM_ORD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_DI_LS, 24, 25), -+ [AN7581_PCS_TXPLL_SSC_DELTA1] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 16, 31), -+ [AN7581_PCS_TXPLL_SSC_DELTA] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_DELTA1, 0, 15), -+ [AN7581_PCS_TXPLL_SSC_TRI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 16, 16), -+ [AN7581_PCS_TXPLL_SSC_PHASE_INI] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 8, 8), -+ [AN7581_PCS_TXPLL_SSC_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_EN, 0, 0), -+ [AN7581_PCS_TXPLL_SSC_PERIOD] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SSC_PERIOD, 0, 15), -+ [AN7581_PCS_TXPLL_LPF_BC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 16, 20), -+ [AN7581_PCS_TXPLL_LPF_BR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 8, 12), -+ [AN7581_PCS_TXPLL_CHP_IOFST] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 0, 5), -+ [AN7581_PCS_TXPLL_CHP_IBIAS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_750M_SYS_CK_EN, 24, 29), -+ [AN7581_PCS_TXPLL_LPF_BWC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 8, 12), -+ [AN7581_PCS_TXPLL_LPF_BWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 0, 4), -+ [AN7581_PCS_TXPLL_LPF_BP] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_CHP_IOFST, 24, 28), -+ [AN7581_PCS_TXPLL_VCO_CFIX] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 16, 17), -+ [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 24, 26), -+ [AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 16, 18), -+ [AN7581_PCS_TXPLL_VCO_TCLVAR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 8, 10), -+ [AN7581_PCS_TXPLL_VCO_SCAPWR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_VCO_SCAPWR, 0, 2), -+ [AN7581_PCS_TXPLL_VCO_HALFLSB_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 24, 24), -+ [AN7581_PCS_TXPLL_KBAND_CODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 24, 31), -+ [AN7581_PCS_TXPLL_KBAND_OPTION] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_LPF_BWR, 16, 16), -+ [AN7581_PCS_TXPLL_KBAND_KS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 24, 25), -+ [AN7581_PCS_TXPLL_KBAND_KF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 16, 17), -+ [AN7581_PCS_TXPLL_KBAND_KFC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 8, 9), -+ [AN7581_PCS_TXPLL_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_KBAND_DIV, 0, 2), -+ [AN7581_PCS_TXPLL_MMD_PREDIV_MODE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 8, 9), -+ [AN7581_PCS_TXPLL_POSTDIV_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_POSTDIV_EN, 0, 0), -+ [AN7581_PCS_TXPLL_VCODIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 8, 9), -+ [AN7581_PCS_TXPLL_TCL_KBAND_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_KBAND_VREF, 0, 4), -+ [AN7581_PCS_TXPLL_TCL_AMP_GAIN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_SDM_OUT, 24, 26), -+ [AN7581_PCS_TXPLL_TCL_AMP_VREF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 0, 4), -+ [AN7581_PCS_TXPLL_TCL_LPF_BW] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_LPF_BW, 0, 2), -+ [AN7581_PCS_TXPLL_TCL_LPF_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, 0, 0), -+ [AN7581_PCS_TXPLL_TCL_AMP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TXPLL_TCL_AMP_VREF, 24, 24), -+ -+ [AN7581_PCS_TX_DMEDGEGEN_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX1_CKLDO_EN, 24, 24), -+ [AN7581_PCS_TX_CKLDO_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_TX1_CKLDO_EN, 0, 0), -+ -+ [AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 24, 24), -+ [AN7581_PCS_RX_DAC_E1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 16, 16), -+ [AN7581_PCS_RX_DAC_E0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 8, 8), -+ [AN7581_PCS_RX_DAC_D1_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_D1_BYPASS_AEQ, 0, 0), -+ [AN7581_PCS_RX_DAC_D0_BYPASS_AEQ] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_PEACKING_CTRL_LSB, 24, 24), -+ [AN7581_PCS_RX_FE_VCM_GEN_PWDB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 24, 24), -+ -+ [AN7581_PCS_AEQ_OFORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_AEQ1_CFORCE, 16, 27), -+ [AN7581_PCS_RX_OSCAL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_OSCAL_WATCH_WNDW, 16, 25), -+ -+ [AN7581_PCS_CDR_PD_EDGE_DIS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PD_PICAL_CKD8_INV, 8, 8), -+ [AN7581_PCS_CDR_PD_PICAL_CKD8_INV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PD_PICAL_CKD8_INV, 0, 0), -+ -+ [AN7581_PCS_RX_DAC_MON] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR, 16, 20), -+ [AN7581_PCS_CDR_PR_XFICK_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_MONPI_EN, 8, 8), -+ [AN7581_PCS_CDR_PR_MONPI_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_MONPI_EN, 0, 0), -+ [AN7581_PCS_CDR_PR_MONPR_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_COR_HBW_EN, 24, 24), -+ -+ [AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_REV_0, 24, 26), -+ [AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_REV_0, 20, 22), -+ [AN7581_PCS_RX_REV_1_SIGDET_ILEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_REV_0, 18, 19), -+ -+ [AN7581_PCS_CDR_LPF_TOP_LIM] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_LPF_RATIO, 8, 26), -+ [AN7581_PCS_CDR_LPF_RATIO] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_LPF_RATIO, 0, 1), -+ -+ [AN7581_PCS_CDR_PR_KBAND_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 24, 26), -+ [AN7581_PCS_CDR_PR_BETA_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 16, 19), -+ [AN7581_PCS_CDR_PR_VCOADC_OS] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 8, 11), -+ [AN7581_PCS_CDR_PR_BETA_DAC] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BETA_DAC, 0, 6), -+ [AN7581_PCS_CDR_PR_FBKSEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 24, 25), -+ [AN7581_PCS_CDR_PR_DAC_BAND] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 16, 20), -+ [AN7581_PCS_CDR_PR_VREG_CKBUF_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 8, 10), -+ [AN7581_PCS_CDR_PR_VREG_IBAND_VAL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_VREG_IBAND_VAL, 0, 2), -+ -+ [AN7581_PCS_RX_FE_VB_EQ3_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 16, 16), -+ [AN7581_PCS_RX_FE_VB_EQ2_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 8, 8), -+ [AN7581_PCS_RX_FE_VB_EQ1_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_VB_EQ1_EN, 0, 0), -+ [AN7581_PCS_RX_FE_EQ_HZEN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_FE_50OHMS_SEL, 24, 24), -+ -+ [AN7581_PCS_CDR_PR_CAP_EN] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR, 8, 8), -+ [AN7581_PCS_CDR_BUF_IN_SR] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_BUF_IN_SR, 0, 2), -+ -+ [AN7581_PCS_RX_SIGDET_VTH_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_SIGDET_NOVTH, 16, 20), -+ [AN7581_PCS_RX_SIGDET_PEAK] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_SIGDET_NOVTH, 8, 9), -+ [AN7581_PCS_RX_SIGDET_LPF_CTRL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_DAC_RANGE_EYE, 24, 25), -+ -+ [AN7581_PCS_RX_TDC_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 24, 24), -+ [AN7581_PCS_RX_PHYCK_RSTB] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 16, 16), -+ [AN7581_PCS_RX_PHYCK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 8, 9), -+ [AN7581_PCS_RX_PHYCK_DIV] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_PHYCK_DIV, 0, 7), -+ [AN7581_PCS_RX_PHY_CK_SEL_FORCE] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_BUSBIT_SEL, 24, 24), -+ [AN7581_PCS_RX_PHY_CK_SEL] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_RX1_BUSBIT_SEL, 16, 16), -+ -+ [AN7581_PCS_CDR_PR_INJ_FORCE_OFF] = REG_FIELD(AIROHA_PCS_ANA_PXP_2L_CDR1_PR_INJ_MODE, 24, 24), -+}; -+ -+static void an7581_pcs_jcpll_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; -+ struct regmap *pcs_pma; -+ u32 kband_vref; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ kband_vref = 0x10; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ kband_vref = 0xf; -+ break; -+ default: -+ return; -+ } -+ -+ /* This comment only apply to Serdes PCIe that expose -+ * 2 PCS. -+ * -+ * The Serdes PCIe expose 2 PCS but always require -+ * the PMA for the first PCS to be configured -+ * for correct functionality for JCPLL. -+ */ -+ pcs_pma = priv->pcs_pma[0]; -+ -+ /* Setup LDO */ -+ usleep_range(200, 300); -+ -+ regmap_field_set_bits(pcs_ana_fields[AN7581_PCS_JCPLL_SPARE_L], -+ AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO); -+ -+ /* Setup RSTB */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_RST_DLY], -+ AIROHA_PCS_ANA_JCPLL_RST_DLY_150_200); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_PLL_RSTB], 0x1); -+ -+ /* Enable PLL force selection and Force Disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN); -+ -+ /* Setup SDM */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_DI_LS], -+ AIROHA_PCS_ANA_JCPLL_SDM_DI_LS_2_23); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_DI_EN], 0x0); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_OUT], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_ORD], -+ AIROHA_PCS_ANA_JCPLL_SDM_ORD_3SDM); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_MODE], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_IFM], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SDM_HREN], 0x0); -+ -+ /* Setup SSC */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_DELTA], 0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_DELTA1], 0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_PERIOD], 0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_TRI_EN], 0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_EN], 0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_SSC_PHASE_INI], 0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_TCLVAR], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L], 0); -+ -+ /* Setup LPF */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_CHP_IOFST], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_CHP_IBIAS], 0x18); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_SHCK_EN], 0); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BWR], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BP], 0x10); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BC], 0x1f); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BR], BIT(3) | BIT(1)); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_LPF_BWC], 0x0); -+ -+ /* Setup VCO */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_SCAPWR], 0x4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_HALFLSB_EN], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_CFIX], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_L], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_VCOVAR_BIAS_H], 0x3); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCO_TCLVAR], 0x3); -+ -+ /* Setup PCW */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_PCW, -+ AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_JCPLL_SDM_PCW, 0x25800000)); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_SDM_PCW); -+ -+ /* Setup DIV */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_POSTDIV_D5], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_MMD_PREDIV_MODE], -+ AIROHA_PCS_ANA_JCPLL_MMD_PREDIV_MODE_2); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_VCODIV], -+ AIROHA_PCS_ANA_JCPLL_VCODIV_1); -+ -+ /* Setup KBand */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_KS], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_KF], 0x3); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_KFC], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_DIV], 0x2); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_CODE], 0xe4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_KBAND_OPTION], 0x0); -+ -+ /* Setup TCL */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_KBAND_VREF], -+ kband_vref); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_AMP_VREF], 0x5); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_AMP_GAIN], -+ AIROHA_PCS_ANA_JCPLL_TCL_AMP_GAIN_4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_AMP_EN], 0x1); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_LPF_BW], -+ AIROHA_PCS_ANA_JCPLL_TCL_LPF_BW_1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_JCPLL_TCL_LPF_EN], 0x1); -+ -+ /* Enable PLL */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN); -+ -+ /* Enale PLL Output */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN | -+ AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN); -+} -+ -+static void an7581_pcs_txpll_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; -+ u32 lpf_chp_ibias, lpf_bp, lpf_bwr, lpf_bwc; -+ struct regmap *pcs_pma; -+ u32 tcl_amp_vref; -+ bool sdm_hren; -+ u32 vco_cfix; -+ bool vcodiv; -+ u32 pcw; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ lpf_chp_ibias = 0xf; -+ lpf_bp = BIT(1); -+ lpf_bwr = BIT(3) | BIT(1) | BIT(0); -+ lpf_bwc = BIT(4) | BIT(3); -+ vco_cfix = BIT(1) | BIT(0); -+ pcw = BIT(27); -+ tcl_amp_vref = BIT(3) | BIT(1) | BIT(0); -+ vcodiv = false; -+ sdm_hren = false; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ lpf_chp_ibias = 0xa; -+ lpf_bp = BIT(2) | BIT(0); -+ lpf_bwr = 0; -+ lpf_bwc = 0; -+ vco_cfix = 0; -+ pcw = BIT(27) | BIT(25); -+ tcl_amp_vref = BIT(3) | BIT(2) | BIT(0); -+ vcodiv = true; -+ sdm_hren = false; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ lpf_chp_ibias = 0xf; -+ lpf_bp = BIT(1); -+ lpf_bwr = BIT(3) | BIT(1) | BIT(0); -+ lpf_bwc = BIT(4) | BIT(3); -+ vco_cfix = BIT(0); -+ pcw = BIT(27) | BIT(22); -+ tcl_amp_vref = BIT(3) | BIT(1) | BIT(0); -+ vcodiv = false; -+ sdm_hren = true; -+ break; -+ default: -+ return; -+ } -+ -+ /* This comment only apply to Serdes PCIe that expose -+ * 2 PCS. -+ * -+ * The Serdes PCIe expose 2 PCS but always require -+ * the PMA for the first PCS to be configured -+ * for correct functionality for TXPLL. -+ */ -+ pcs_pma = priv->pcs_pma[0]; -+ -+ /* Setup VCO LDO Output */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LDO_VCO_OUT], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LDO_OUT], 0x1); -+ -+ /* Setup RSTB */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_PLL_RSTB], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_RST_DLY], 0x4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_REFIN_DIV], -+ AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_REFIN_INTERNAL], 0x1); -+ -+ /* Enable PLL force selection and Force Disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN); -+ -+ /* Setup SDM */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_MODE], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_IFM], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_DI_LS], -+ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_DI_EN], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_HREN], sdm_hren); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_OUT], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SDM_ORD], -+ AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM); -+ -+ /* Setup SSC */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_DELTA1], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_DELTA], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_TRI_EN], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_PHASE_INI], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_EN], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_SSC_PERIOD], 0x0); -+ -+ /* Setup LPF */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_CHP_IBIAS], -+ lpf_chp_ibias); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_CHP_IOFST], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BC], 0x1f); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BR], 0x5); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BWC], lpf_bwc); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BWR], lpf_bwr); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_LPF_BP], lpf_bp); -+ -+ /* Setup VCO */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_CFIX], vco_cfix); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_L], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_VCOVAR_BIAS_H], 0x4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_TCLVAR], 0x4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_SCAPWR], 0x7); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCO_HALFLSB_EN], 0x1); -+ -+ /* Setup PCW */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW, -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); -+ -+ /* Setup KBand */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_CODE], 0xe4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_OPTION], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_KS], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_KF], 0x3); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_KFC], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_KBAND_DIV], 0x4); -+ -+ /* Setup DIV */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_POSTDIV_EN], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_MMD_PREDIV_MODE], -+ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_VCODIV], -+ vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 : -+ AIROHA_PCS_ANA_TXPLL_VCODIV_1); -+ -+ /* Setup TCL */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_KBAND_VREF], 0xf); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_AMP_VREF], -+ tcl_amp_vref); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_AMP_GAIN], -+ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_LPF_BW], -+ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_LPF_EN], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TXPLL_TCL_AMP_EN], 0x1); -+ -+ /* Enable PLL */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN); -+ -+ /* Enale PLL Output */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN | -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN); -+} -+ -+static void an7581_pcs_tx_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 fir_cn1, fir_c0b, fir_c1; -+ u32 tx_rate_ctrl; -+ u32 ckin_divisor; -+ u32 xfi_tx_mode; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ ckin_divisor = BIT(1); -+ tx_rate_ctrl = BIT(0); -+ fir_cn1 = 0; -+ fir_c0b = 12; -+ fir_c1 = 0; -+ xfi_tx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_1G25; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ ckin_divisor = BIT(2); -+ tx_rate_ctrl = BIT(0); -+ fir_cn1 = 0; -+ fir_c0b = 11; -+ fir_c1 = 1; -+ xfi_tx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_3G12; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ ckin_divisor = BIT(2) | BIT(0); -+ tx_rate_ctrl = BIT(1); -+ fir_cn1 = 1; -+ fir_c0b = 1; -+ fir_c1 = 11; -+ xfi_tx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_10G3; -+ break; -+ default: -+ return; -+ } -+ -+ /* Set TX rate ctrl */ -+ if (priv->data->port_type == AIROHA_PCS_PCIE) { -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_29, -+ AIROHA_PCS_PMA_2L_TX_RATE_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_2L_TX_RATE_CTRL, -+ tx_rate_ctrl)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_ADD_XPON_MODE_1, -+ AIROHA_PCS_PMA_XFI_TX_MODE, -+ xfi_tx_mode); -+ } else { -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_XPON_TX_RATE_CTRL, -+ AIROHA_PCS_PMA_PON_TX_RATE_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_PON_TX_RATE_CTRL, -+ tx_rate_ctrl)); -+ } -+ -+ /* Setup TX Config */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TX_DMEDGEGEN_EN], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_TX_CKLDO_EN], 0x1); -+ -+ udelay(1); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL | -+ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL); -+ -+ /* FIXME: Ask Airoha TX term is OK to reset? */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_TERM_SEL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | -+ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_TERM_SEL | -+ AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR, -+ ckin_divisor) | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_TERM_SEL, 0x0)); -+ -+ if (priv->data->port_type != AIROHA_PCS_PCIE) { -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | -+ AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, -+ tx_rate_ctrl)); -+ } -+ -+ /* Setup TX FIR Load Parameters (Reference 660mV) */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C0B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1, fir_cn1) | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, fir_c0b)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C1, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, fir_c1)); -+ -+ /* Reset TX Bar */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_TX_RST_B, -+ AIROHA_PCS_PMA_TXCALIB_RST_B | AIROHA_PCS_PMA_TX_TOP_RST_B); -+} -+ -+static void an7581_pcs_rx_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 phyck_div, phyck_sel; -+ u32 pr_cdr_beta_dac; -+ u32 cdr_pr_buf_in_sr; -+ bool cdr_pr_cap_en; -+ u32 sigdet_vth_sel; -+ u32 rx_rate_ctrl; -+ u32 xfi_rx_mode; -+ u32 osr; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ osr = BIT(1) | BIT(0); /* 1.25G */ -+ pr_cdr_beta_dac = BIT(3); -+ rx_rate_ctrl = 0; -+ cdr_pr_cap_en = false; -+ cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0); -+ sigdet_vth_sel = BIT(2) | BIT(1); -+ phyck_div = BIT(5) | BIT(3) | BIT(0); -+ phyck_sel = BIT(0); -+ xfi_rx_mode = AIROHA_PCS_PMA_XFI_TX_MODE_1G25; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ osr = BIT(0); /* 2.5G */ -+ pr_cdr_beta_dac = BIT(2) | BIT(1); -+ rx_rate_ctrl = 0; -+ cdr_pr_cap_en = true; -+ cdr_pr_buf_in_sr = BIT(2) | BIT(1); -+ sigdet_vth_sel = BIT(2) | BIT(1); -+ phyck_div = BIT(3) | BIT(1) | BIT(0); -+ phyck_sel = BIT(0); -+ xfi_rx_mode = AIROHA_PCS_PMA_XFI_RX_MODE_3G12; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ osr = 0; /* 10G */ -+ cdr_pr_cap_en = false; -+ pr_cdr_beta_dac = BIT(3); -+ rx_rate_ctrl = BIT(1); -+ cdr_pr_buf_in_sr = BIT(2) | BIT(1) | BIT(0); -+ sigdet_vth_sel = BIT(1); -+ phyck_div = BIT(6) | BIT(1); -+ phyck_sel = BIT(1); -+ xfi_rx_mode = AIROHA_PCS_PMA_XFI_RX_MODE_10G3; -+ break; -+ default: -+ return; -+ } -+ -+ /* Set RX rate ctrl */ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_2, -+ AIROHA_PCS_PMA_CK_RATE, -+ AIROHA_PCS_PMA_CK_RATE_10); -+ -+ if (priv->data->port_type == AIROHA_PCS_PCIE) { -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_29, -+ AIROHA_PCS_PMA_2L_RX_RATE_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_2L_RX_RATE_CTRL, -+ rx_rate_ctrl)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_ADD_XPON_MODE_1, -+ AIROHA_PCS_PMA_XFI_RX_MODE, -+ xfi_rx_mode); -+ } else { -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_XPON_RX_RESERVED_1, -+ AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, -+ rx_rate_ctrl)); -+ } -+ -+ /* Setup RX Path */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_5, -+ AIROHA_PCS_PMA_FLL_IDAC_MIN | -+ AIROHA_PCS_PMA_FLL_IDAC_MAX, -+ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MIN, 0x400) | -+ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MAX, 0x3ff)); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_EYE_BYPASS_AEQ], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_E1_BYPASS_AEQ], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_E0_BYPASS_AEQ], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_D1_BYPASS_AEQ], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_D0_BYPASS_AEQ], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VCM_GEN_PWDB], 0x1); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1, -+ AIROHA_PCS_PMA_LCPLL_MAN_PWDB); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_AEQ_OFORCE], -+ AIROHA_PCS_ANA_AEQ_OFORCE_CTLE); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_OSCAL_FORCE], -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4, -+ AIROHA_PCS_PMA_DISB_BLWC_OFFSET); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL, -+ AIROHA_PCS_PMA_DISB_LEQ); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PD_EDGE_DIS], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PD_PICAL_CKD8_INV], 0x0); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_AEQ_BYPASS, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON | -+ AIROHA_PCS_PMA_FORCE_DA_AEQ_CKON, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_CKON); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_AEQ_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_DAC_MON], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_XFICK_EN], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_MONPI_EN], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_MONPR_EN], 0x0); -+ -+ /* Setup FE Gain and FE Peacking */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL | -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, 0x0)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, 0x0)); -+ -+ /* Setup FE VOS */ -+ if (interface != PHY_INTERFACE_MODE_USXGMII && -+ interface != PHY_INTERFACE_MODE_10GBASER) -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_VOS, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS | -+ AIROHA_PCS_PMA_FORCE_DA_FE_VOS, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_FE_VOS | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_FE_VOS, 0x0)); -+ -+ /* Setup FLL PR FMeter (no bypass mode)*/ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_0, -+ AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT, -+ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_CYCLECNT, 0x1)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_1, -+ AIROHA_PCS_PMA_PLL_LOCK_TARGET_END | -+ AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG, -+ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_END, 0xffff) | -+ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG, 0x0)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PLL_TDC_FREQDET_3, -+ AIROHA_PCS_PMA_PLL_LOCK_LOCKTH, -+ FIELD_PREP(AIROHA_PCS_PMA_PLL_LOCK_LOCKTH, 0x1)); -+ -+ /* FIXME: Warn and Ask Airoha about typo in air_eth_xsgmii.c line 1391 */ -+ /* AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL is set 0x0 in SDK but seems a typo */ -+ /* Setup REV */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_REV_1_FE_BUF1_BIAS_CTRL], -+ BIT(2)); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_REV_1_FE_BUF2_BIAS_CTRL], -+ BIT(2)); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_REV_1_SIGDET_ILEAK], 0x0); -+ -+ /* Setup Rdy Timeout */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5, -+ AIROHA_PCS_PMA_RX_RDY | -+ AIROHA_PCS_PMA_RX_BLWC_RDY_EN, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_RDY, 0xa) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_BLWC_RDY_EN, 0x5)); -+ -+ /* Setup CaBoundry Init */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0, -+ AIROHA_PCS_PMA_RX_OS_START | -+ AIROHA_PCS_PMA_OSC_SPEED_OPT, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_START, 0x1) | -+ AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6, -+ AIROHA_PCS_PMA_RX_OS_END, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_END, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1, -+ AIROHA_PCS_PMA_RX_PICAL_END | -+ AIROHA_PCS_PMA_RX_PICAL_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_END, 0x32) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_START, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4, -+ AIROHA_PCS_PMA_RX_SDCAL_END | -+ AIROHA_PCS_PMA_RX_SDCAL_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_END, 0x32) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_START, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2, -+ AIROHA_PCS_PMA_RX_PDOS_END | -+ AIROHA_PCS_PMA_RX_PDOS_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_END, 0x32) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_START, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3, -+ AIROHA_PCS_PMA_RX_FEOS_END | -+ AIROHA_PCS_PMA_RX_FEOS_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_END, 0x32) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_START, 0x2)); -+ -+ /* Setup By Serdes*/ -+ /* Setup RX OSR */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_AEQ_SPEED, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | -+ AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, osr)); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PD_EDGE_DIS], !!osr); -+ -+ /* Setup CDR LPF Ratio */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_LPF_TOP_LIM], 0x20000); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_LPF_RATIO], osr); -+ -+ /* Setup CDR PR */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_KBAND_DIV], 0x4); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_BETA_SEL], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_VCOADC_OS], 0x8); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_BETA_DAC], -+ pr_cdr_beta_dac); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_FBKSEL], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_DAC_BAND], -+ pr_cdr_beta_dac); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_VREG_CKBUF_VAL], 0x6); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_VREG_IBAND_VAL], 0x6); -+ -+ /* Setup Eye Mon */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2, -+ AIROHA_PCS_PMA_EQ_DEBUG_SEL | -+ AIROHA_PCS_PMA_FOM_NUM_ORDER | -+ AIROHA_PCS_PMA_A_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_DEBUG_SEL, 0x0) | -+ FIELD_PREP(AIROHA_PCS_PMA_FOM_NUM_ORDER, 0x1) | -+ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x3)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, -+ AIROHA_PCS_PMA_DATA_SHIFT | -+ AIROHA_PCS_PMA_EYECNT_FAST, -+ AIROHA_PCS_PMA_EYECNT_FAST); -+ -+ /* Calibration Start */ -+ -+ /* Enable SYS */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_SYS_EN_SEL_0, -+ AIROHA_PCS_PMA_RX_SYS_EN_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_SYS_EN_SEL, 0x1)); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0, -+ AIROHA_PCS_PMA_SW_LCPLL_EN); -+ -+ usleep_range(500, 600); -+ -+ /* Setup FLL PR FMeter (bypass mode)*/ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, -+ AIROHA_PCS_PMA_DISB_FBCK_LOCK); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_FBCK_LOCK); -+ -+ /* Enable CMLEQ */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_EQ_HZEN], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VB_EQ3_EN], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VB_EQ2_EN], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_FE_VB_EQ1_EN], 0x1); -+ -+ /* Setup CDR PR */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_CAP_EN], -+ cdr_pr_cap_en); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_BUF_IN_SR], -+ cdr_pr_buf_in_sr); -+ -+ /* Setup CDR xxx Pwdb, set force and disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B | -+ AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, -+ AIROHA_PCS_PMA_XPON_CDR_PD_PWDB | -+ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | -+ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | -+ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); -+ -+ /* FIXME: Ask Airoha WHY it's cleared? */ -+ /* regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, -+ * AIROHA_PCS_ANA_RX_FE_50OHMS_SEL); -+ */ -+ -+ /* Setup SigDet */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_SIGDET_VTH_SEL], -+ sigdet_vth_sel); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_SIGDET_PEAK], -+ BIT(1)); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_SIGDET_LPF_CTRL], -+ BIT(1) | BIT(0)); -+ -+ /* Disable SigDet Pwdb */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, -+ AIROHA_PCS_PMA_RX_SIDGET_PWDB); -+ -+ /* Setup PHYCK */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_TDC_CK_SEL], 0x0); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHYCK_RSTB], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHYCK_SEL], -+ phyck_sel); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHYCK_DIV], -+ phyck_div); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHY_CK_SEL_FORCE], 0x1); -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_RX_PHY_CK_SEL], 0x0); -+ -+ usleep_range(100, 200); -+ -+ /* Enable CDR xxx Pwdb */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, -+ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, -+ AIROHA_PCS_PMA_XPON_CDR_PD_PWDB | -+ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | -+ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | -+ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); -+ -+ /* Enable SigDet Pwdb */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, -+ AIROHA_PCS_PMA_RX_SIDGET_PWDB); -+} -+ -+static unsigned int an7581_pcs_apply_cdr_pr_idac(struct airoha_pcs_priv *priv, -+ int index, u32 cdr_pr_idac) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 val; -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, -+ AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC, -+ cdr_pr_idac)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, -+ AIROHA_PCS_PMA_FREQLOCK_DET_EN, -+ AIROHA_PCS_PMA_FREQLOCK_DET_EN_FORCE_0); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, -+ AIROHA_PCS_PMA_FREQLOCK_DET_EN, -+ AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL); -+ -+ usleep_range(5000, 7000); -+ -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_RX_FREQDET, &val); -+ -+ return FIELD_GET(AIROHA_PCS_PMA_FL_OUT, val); -+} -+ -+static u32 an7581_pcs_rx_prcal_idac_major(struct airoha_pcs_priv *priv, -+ int index, u32 target_fl_out) -+{ -+ unsigned int fl_out_diff = UINT_MAX; -+ unsigned int prcal_search; -+ u32 cdr_pr_idac = 0; -+ -+ for (prcal_search = 0; prcal_search < 8 ; prcal_search++) { -+ unsigned int fl_out_diff_new; -+ unsigned int fl_out; -+ u32 cdr_pr_idac_tmp; -+ -+ /* try to find the upper value by setting the last 3 bit */ -+ cdr_pr_idac_tmp = FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, -+ prcal_search); -+ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac_tmp); -+ -+ /* Use absolute values to find the closest one to target */ -+ fl_out_diff_new = abs(fl_out - target_fl_out); -+ dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", -+ cdr_pr_idac_tmp, fl_out, fl_out_diff_new); -+ if (fl_out_diff_new < fl_out_diff) { -+ cdr_pr_idac = cdr_pr_idac_tmp; -+ fl_out_diff = fl_out_diff_new; -+ } -+ } -+ -+ return cdr_pr_idac; -+} -+ -+static u32 an7581_pcs_rx_prcal_idac_minor(struct airoha_pcs_priv *priv, int index, -+ u32 target_fl_out, u32 cdr_pr_idac_major) -+{ -+ unsigned int remaining_prcal_search_bits = 0; -+ u32 cdr_pr_idac = cdr_pr_idac_major; -+ unsigned int fl_out, fl_out_diff; -+ int best_prcal_search_bit = -1; -+ int prcal_search_bit; -+ -+ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac); -+ fl_out_diff = abs(fl_out - target_fl_out); -+ -+ /* Deadline search part. -+ * We start from top bits to bottom as we progressively decrease the -+ * signal. -+ */ -+ for (prcal_search_bit = 7; prcal_search_bit >= 0; prcal_search_bit--) { -+ unsigned int fl_out_diff_new; -+ u32 cdr_pr_idac_tmp; -+ -+ cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit); -+ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac_tmp); -+ -+ /* Use absolute values to find the closest one to target */ -+ fl_out_diff_new = abs(fl_out - target_fl_out); -+ dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", -+ cdr_pr_idac_tmp, fl_out, fl_out_diff_new); -+ if (fl_out_diff_new < fl_out_diff) { -+ best_prcal_search_bit = prcal_search_bit; -+ fl_out_diff = fl_out_diff_new; -+ } -+ } -+ -+ /* Set the idac with the best value we found and -+ * reset the search bit to start from bottom to top. -+ */ -+ if (best_prcal_search_bit >= 0) { -+ cdr_pr_idac |= BIT(best_prcal_search_bit); -+ remaining_prcal_search_bits = best_prcal_search_bit; -+ prcal_search_bit = 0; -+ } -+ -+ /* Fine tune part. -+ * Test remaining bits to find an even closer signal level to target -+ * by increasing the signal. -+ */ -+ while (remaining_prcal_search_bits) { -+ unsigned int fl_out_diff_new; -+ u32 cdr_pr_idac_tmp; -+ -+ cdr_pr_idac_tmp = cdr_pr_idac | BIT(prcal_search_bit); -+ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac_tmp); -+ -+ /* Use absolute values to find the closest one to target */ -+ fl_out_diff_new = abs(fl_out - target_fl_out); -+ /* Assume we found the deadline when the new absolue signal difference -+ * from target is greater than the previous and the difference is at -+ * least 10% greater between the old and new value. -+ * This is to account for signal detection level tollerance making -+ * sure we are actually over a deadline (AKA we are getting farther -+ * from target) -+ */ -+ dev_dbg(priv->dev, "Tested CDR Pr Idac: %x Fl Out: %x Diff: %u\n", -+ cdr_pr_idac_tmp, fl_out, fl_out_diff_new); -+ if (fl_out_diff_new > fl_out_diff && -+ (abs(fl_out_diff_new - fl_out_diff) * 100) / fl_out_diff > 10) { -+ /* Exit early if we are already at the deadline */ -+ if (prcal_search_bit == 0) -+ break; -+ -+ /* We found the deadline, set the value to the previous -+ * bit, and reset the loop to fine tune with the -+ * remaining values. -+ */ -+ cdr_pr_idac |= BIT(prcal_search_bit - 1); -+ remaining_prcal_search_bits = prcal_search_bit - 1; -+ prcal_search_bit = 0; -+ } else { -+ /* Update the signal level diff and try the next bit */ -+ fl_out_diff = fl_out_diff_new; -+ -+ /* If we didn't found the deadline, set the last bit -+ * and reset the loop to fine tune with the remainig -+ * values. -+ */ -+ if (prcal_search_bit == remaining_prcal_search_bits - 1) { -+ cdr_pr_idac |= BIT(prcal_search_bit); -+ remaining_prcal_search_bits = prcal_search_bit; -+ prcal_search_bit = 0; -+ } else { -+ prcal_search_bit++; -+ } -+ } -+ } -+ -+ return cdr_pr_idac; -+} -+ -+static void an7581_pcs_rx_prcal(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 cdr_pr_idac_major, cdr_pr_idac; -+ unsigned int fl_out, fl_out_diff; -+ -+ u32 target_fl_out; -+ u32 cyclecnt; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: /* DS_1.25G / US_1.25G */ -+ case PHY_INTERFACE_MODE_1000BASEX: -+ target_fl_out = 0xa3d6; -+ cyclecnt = 32767; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: /* DS_9.95328G / US_9.95328G */ -+ target_fl_out = 0xa000; -+ cyclecnt = 20000; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: /* DS_10.3125G / US_1.25G */ -+ case PHY_INTERFACE_MODE_10GBASER: -+ target_fl_out = 0x9edf; -+ cyclecnt = 32767; -+ break; -+ default: -+ return; -+ } -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_REF_RST_N); -+ -+ usleep_range(100, 200); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_2, -+ AIROHA_PCS_PMA_LOCK_TARGET_END | -+ AIROHA_PCS_PMA_LOCK_TARGET_BEG, -+ FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_END, target_fl_out + 100) | -+ FIELD_PREP(AIROHA_PCS_PMA_LOCK_TARGET_BEG, target_fl_out - 100)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_1, -+ AIROHA_PCS_PMA_UNLOCK_CYCLECNT | -+ AIROHA_PCS_PMA_LOCK_CYCLECNT, -+ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_CYCLECNT, cyclecnt) | -+ FIELD_PREP(AIROHA_PCS_PMA_LOCK_CYCLECNT, cyclecnt)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_4, -+ AIROHA_PCS_PMA_LOCK_UNLOCKTH | -+ AIROHA_PCS_PMA_LOCK_LOCKTH, -+ FIELD_PREP(AIROHA_PCS_PMA_LOCK_UNLOCKTH, 3) | -+ FIELD_PREP(AIROHA_PCS_PMA_LOCK_LOCKTH, 3)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_3, -+ AIROHA_PCS_PMA_UNLOCK_TARGET_END | -+ AIROHA_PCS_PMA_UNLOCK_TARGET_BEG, -+ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_END, target_fl_out + 100) | -+ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_TARGET_BEG, target_fl_out - 100)); -+ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_INJ_FORCE_OFF], 0x1); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_C_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_R_EN | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_LPF_R_EN | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); -+ -+ /* Calibration logic: -+ * First check the major value by looping with every -+ * value in the last 3 bit of CDR_PR_IDAC. -+ * Get the signal level and save the value that is closer to -+ * the target. -+ * -+ * Then check each remaining 7 bits in search of the deadline -+ * where the signal gets farther than signal target. -+ * -+ * Finally fine tune for the remaining bits to find the one that -+ * produce the closest signal level. -+ */ -+ cdr_pr_idac_major = an7581_pcs_rx_prcal_idac_major(priv, index, target_fl_out); -+ -+ cdr_pr_idac = an7581_pcs_rx_prcal_idac_minor(priv, index, -+ target_fl_out, cdr_pr_idac_major); -+ -+ fl_out = an7581_pcs_apply_cdr_pr_idac(priv, index, cdr_pr_idac); -+ fl_out_diff = abs(fl_out - target_fl_out); -+ if (fl_out_diff > 100) { -+ u32 pr_idac_major = FIELD_GET(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, -+ cdr_pr_idac_major); -+ unsigned int fl_out_tmp, fl_out_diff_tmp; -+ u32 cdr_pr_idac_tmp; -+ -+ if (pr_idac_major > 0) { -+ cdr_pr_idac_tmp = FIELD_PREP(AIROHA_PCS_PMA_FORCE_CDR_PR_IDAC_MAJOR, -+ pr_idac_major - 1); -+ -+ dev_dbg(priv->dev, "Fl Out is %d far from target %d with Pr Idac %x. Trying with Pr Idac %x.\n", -+ fl_out_diff, target_fl_out, cdr_pr_idac_major, cdr_pr_idac_tmp); -+ -+ cdr_pr_idac_tmp = an7581_pcs_rx_prcal_idac_minor(priv, index, -+ target_fl_out, -+ cdr_pr_idac_tmp); -+ -+ fl_out_tmp = an7581_pcs_apply_cdr_pr_idac(priv, index, -+ cdr_pr_idac_tmp); -+ fl_out_diff_tmp = abs(fl_out_tmp - target_fl_out); -+ if (fl_out_diff_tmp < fl_out_diff) { -+ fl_out = fl_out_tmp; -+ fl_out_diff = fl_out_diff_tmp; -+ cdr_pr_idac = cdr_pr_idac_tmp; -+ } -+ } -+ } -+ dev_dbg(priv->dev, "Selected CDR Pr Idac: %x Fl Out: %x\n", cdr_pr_idac, fl_out); -+ if (fl_out_diff > 100) -+ dev_dbg(priv->dev, "Fl Out is %d far from target %d on intermediate calibration.\n", -+ fl_out_diff, target_fl_out); -+ -+ /* Setup Load Band */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CDR_PR_INJ_FORCE_OFF], 0x0); -+ -+ /* Disable force of LPF C previously enabled */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_LPF_C_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_LPF_C_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_B, -+ AIROHA_PCS_PMA_LOAD_EN); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_1, -+ AIROHA_PCS_PMA_LPATH_IDAC, -+ FIELD_PREP(AIROHA_PCS_PMA_LPATH_IDAC, cdr_pr_idac)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_REF_RST_N); -+ -+ usleep_range(100, 200); -+} -+ -+/* This is used to both calibrate and lock to signal (after a previous -+ * calibration) after a global reset. -+ */ -+static void an7581_pcs_cdr_reset(struct airoha_pcs_priv *priv, int index, -+ phy_interface_t interface, bool calibrate) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ /* Setup LPF L2D force and disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); -+ -+ /* Calibrate IDAC and setup Load Band */ -+ if (calibrate) -+ an7581_pcs_rx_prcal(priv, index, interface); -+ -+ /* Setup LPF RSTB force and disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); -+ -+ usleep_range(700, 1000); -+ -+ /* Force Enable LPF RSTB */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); -+ -+ usleep_range(100, 200); -+ -+ /* Force Enable LPF L2D */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); -+ -+ /* Disable LPF RSTB force bit */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); -+ -+ /* Disable LPF L2D force bit */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); -+} -+ -+static int an7581_pcs_phya_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ int calibration_try = 0; -+ u32 val; -+ -+ an7581_pcs_tx_bringup(priv, index, interface); -+ an7581_pcs_rx_bringup(priv, index, interface); -+ -+ usleep_range(100, 200); -+ -+retry_calibration: -+ an7581_pcs_cdr_reset(priv, index, interface, priv->manual_rx_calib); -+ -+ /* Global reset clear */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N | -+ AIROHA_PCS_PMA_SW_REF_RST_N | -+ AIROHA_PCS_PMA_SW_ALLPCS_RST_N | -+ AIROHA_PCS_PMA_SW_PMA_RST_N | -+ AIROHA_PCS_PMA_SW_TX_RST_N | -+ AIROHA_PCS_PMA_SW_RX_RST_N | -+ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N, -+ AIROHA_PCS_PMA_SW_REF_RST_N); -+ -+ usleep_range(100, 200); -+ -+ /* Global reset */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N | -+ AIROHA_PCS_PMA_SW_REF_RST_N | -+ AIROHA_PCS_PMA_SW_ALLPCS_RST_N | -+ AIROHA_PCS_PMA_SW_PMA_RST_N | -+ AIROHA_PCS_PMA_SW_TX_RST_N | -+ AIROHA_PCS_PMA_SW_RX_RST_N | -+ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N); -+ -+ usleep_range(5000, 7000); -+ -+ an7581_pcs_cdr_reset(priv, index, interface, false); -+ -+ /* Manual RX calibration is required only for SoC before E2 -+ * revision. E2+ SoC autocalibrate RX and only CDR reset is needed. -+ */ -+ if (!priv->manual_rx_calib) -+ return 0; -+ -+ /* It was discovered that after a global reset and auto mode gets -+ * actually enabled, the fl_out from calibration might change and -+ * might deviates a lot from the expected value it was calibrated for. -+ * To correctly work, the PCS FreqDet module needs to Lock to the fl_out -+ * (frequency level output) or no signal can correctly be transmitted. -+ * This is detected by checking the FreqDet module Lock bit. -+ * -+ * If it's detected that the FreqDet module is not locked, retry -+ * calibration. From observation on real hardware with a 10g SFP module, -+ * it required a maximum of an additional calibration to actually make -+ * the FreqDet module to lock. Try 10 times before failing to handle -+ * really strange case. -+ */ -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_RX_FREQDET, &val); -+ if (!(val & AIROHA_PCS_PMA_FBCK_LOCK)) { -+ if (calibration_try > AIROHA_PCS_MAX_CALIBRATION_TRY) { -+ dev_err(priv->dev, "No FBCK Lock from FreqDet module after %d calibration try. PCS won't work.\n", -+ AIROHA_PCS_MAX_CALIBRATION_TRY); -+ return -EIO; -+ } -+ -+ calibration_try++; -+ -+ dev_dbg(priv->dev, "No FBCK Lock from FreqDet module, retry calibration.\n"); -+ goto retry_calibration; -+ } -+ -+ return 0; -+} -+ -+static void an7581_pcs_pll_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ an7581_pcs_jcpll_bringup(priv, index, interface); -+ -+ usleep_range(200, 300); -+ -+ an7581_pcs_txpll_bringup(priv, index, interface); -+ -+ usleep_range(200, 300); -+} -+ -+int an7581_pcs_bringup(struct airoha_pcs_priv *priv, int index, -+ phy_interface_t interface) -+{ -+ struct regmap_field **pcs_ana_fields = priv->pcs_ana_fields[index]; -+ -+ /* Enable Analog Common Lane */ -+ regmap_field_write(pcs_ana_fields[AN7581_PCS_CMN_EN], 0x1); -+ -+ /* Setup PLL */ -+ an7581_pcs_pll_bringup(priv, index, interface); -+ -+ msleep(100); -+ -+ /* Setup PHYA */ -+ return an7581_pcs_phya_bringup(priv, index, interface); -+} -+ -+int an7581_pcs_usb_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ int ret; -+ -+ ret = phy_set_mode_ext(priv->phy, PHY_MODE_ETHERNET, interface); -+ if (ret) -+ return ret; -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) { -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_8, -+ AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTR | -+ AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD1 | -+ AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD0, -+ FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTR, 0xf) | -+ FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD1, 0xc) | -+ FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_CDR_BICLTD0, 0x3)); -+ -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_6, -+ AIROHA_PCS_HSGMII_ANA_FORCE_CDR_BIC); -+ } else { -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_6, -+ AIROHA_PCS_HSGMII_ANA_FORCE_CDR_BIC); -+ } -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_26, -+ AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY, -+ AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RST_DLY_32); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_24, -+ AIROHA_PCS_HSGMII_ANA_SSUSB_LN0_CDR_RESERVE); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_18, -+ AIROHA_PCS_HSGMII_ANA_SSUSB_BG_DIV, -+ FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_BG_DIV, 0x1)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_19, -+ AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE, -+ FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE, -+ FIELD_PREP(AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_HV, -+ AIROHA_PCS_HSGMII_ANA_SSUSB_XTAL_TOP_RESERVE_NS_MONPLL_CK))); -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_11, -+ AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, -+ AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_HSGMII); -+ else -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_HSGMII_ANA_SGMII_PHYA_11, -+ AIROHA_PCS_HSGMII_ANA_TPHY_SPEED, -+ AIROHA_PCS_HSGMII_ANA_TPHY_SPEED_SGMII); -+ -+ return 0; -+} -+ -+void an7581_pcs_phya_link_up(struct airoha_pcs_priv *priv, int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ /* Reset TXPCS on link up */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); -+ -+ usleep_range(100, 200); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); -+} -+ -+static int __an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv, int index, -+ const struct reg_field *fields) -+{ -+ struct device *dev = priv->dev; -+ int i; -+ -+ priv->pcs_ana_fields[index] = devm_kcalloc(dev, AN7581_PCS_FIELDS_MAX, -+ sizeof(*priv->pcs_ana_fields[index]), -+ GFP_KERNEL); -+ if (!priv->pcs_ana_fields[index]) -+ return -ENOMEM; -+ -+ for (i = 0; i < AN7581_PCS_FIELDS_MAX; i++) { -+ struct regmap_field *field; -+ -+ field = devm_regmap_field_alloc(dev, priv->pcs_ana, -+ fields[i]); -+ if (IS_ERR(field)) -+ return PTR_ERR(field); -+ -+ priv->pcs_ana_fields[index][i] = field; -+ } -+ -+ return 0; -+} -+ -+int an7581_pcs_alloc_regmap_fields(struct airoha_pcs_priv *priv) -+{ -+ return __an7581_pcs_alloc_regmap_fields(priv, 0, an7581_pcs_fields); -+} -+ -+int an7581_pcs_pcie_alloc_regmap_fields(struct airoha_pcs_priv *priv) -+{ -+ int ret; -+ -+ ret = __an7581_pcs_alloc_regmap_fields(priv, 0, an7581_pcs_pcie0_fields); -+ if (ret) -+ return ret; -+ -+ return __an7581_pcs_alloc_regmap_fields(priv, 1, an7581_pcs_pcie1_fields); -+} -+ -+static bool an7581_pcs_have_rx_signal(struct airoha_pcs_priv *priv, int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ unsigned int count = 0; -+ u32 val; -+ int i; -+ -+ regmap_write(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_0, -+ AIROHA_PCS_TRIGGER_RX_SIDGET_SCAN); -+ -+ /* Scan 5 times for RX sigdet module to detect RX signal */ -+ for (i = 0; i <= 5; i++) { -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_DIG_RO_RESERVE_2, -+ &val); -+ if (val & AIROHA_PCS_RX_SIGDET) -+ count++; -+ } -+ -+ /* Consider signal presence if we detect signal at least 4 times */ -+ return count >= 4; -+} -+ -+int an7581_pcs_rxlock_workaround(struct airoha_pcs_priv *priv, int index) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ u32 val; -+ -+ /* Check if PCS is UP or Down */ -+ regmap_read(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_STUS_1, &val); -+ if (val & AIROHA_PCS_USXGMII_PCS_RX_LINK_STATUS_UP) -+ return 0; -+ -+ /* Validate if this is consistent with RX SigDet module */ -+ if (!an7581_pcs_have_rx_signal(priv, index)) -+ return 0; -+ -+ /* If PCS is down but RX SigDet module detected signal, -+ * trigger CDR reset. -+ */ -+ an7581_pcs_cdr_reset(priv, index, PHY_INTERFACE_MODE_NA, false); -+ -+ /* Report there is an error with Link Detection and we -+ * should test again later. -+ */ -+ return -EINVAL; -+} diff --git a/target/linux/airoha/patches-6.12/310-10-net-airoha-add-phylink-support-for-GDM2-3-4.patch b/target/linux/airoha/patches-6.12/310-10-net-airoha-add-phylink-support-for-GDM2-3-4.patch deleted file mode 100644 index 7421c01c06e..00000000000 --- a/target/linux/airoha/patches-6.12/310-10-net-airoha-add-phylink-support-for-GDM2-3-4.patch +++ /dev/null @@ -1,281 +0,0 @@ -From ee93671d30d7741a39026c2aaaa6a7729929c347 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 17 Jan 2025 13:23:13 +0100 -Subject: [PATCH 2/2] net: airoha: add phylink support for GDM2/3/4 - -Add phylink support for GDM2/3/4 port that require configuration of the -PCS to make the external PHY or attached SFP cage work. - -These needs to be defined in the GDM port node using the pcs-handle -property. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/Kconfig | 1 + - drivers/net/ethernet/airoha/airoha_eth.c | 146 +++++++++++++++++++++- - drivers/net/ethernet/airoha/airoha_eth.h | 3 + - drivers/net/ethernet/airoha/airoha_regs.h | 12 ++ - 4 files changed, 161 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/airoha/Kconfig -+++ b/drivers/net/ethernet/airoha/Kconfig -@@ -20,6 +20,7 @@ config NET_AIROHA - depends on NET_DSA || !NET_DSA - select NET_AIROHA_NPU - select PAGE_POOL -+ select PHYLINK - help - This driver supports the gigabit ethernet MACs in the - Airoha SoC family. ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -71,6 +72,11 @@ static void airoha_qdma_irq_disable(stru - airoha_qdma_set_irqmask(irq_bank, index, mask, 0); - } - -+static bool airhoa_is_phy_external(struct airoha_gdm_port *port) -+{ -+ return port->id != 1; -+} -+ - static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) - { - struct airoha_eth *eth = port->qdma->eth; -@@ -1716,6 +1722,17 @@ static int airoha_dev_open(struct net_de - struct airoha_qdma *qdma = port->qdma; - u32 pse_port = FE_PSE_PORT_PPE1; - -+ if (airhoa_is_phy_external(port)) { -+ err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0); -+ if (err) { -+ netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -+ err); -+ return err; -+ } -+ -+ phylink_start(port->phylink); -+ } -+ - netif_tx_start_all_queues(dev); - err = airoha_set_vip_for_gdm_port(port, true); - if (err) -@@ -1777,6 +1794,11 @@ static int airoha_dev_stop(struct net_de - } - } - -+ if (airhoa_is_phy_external(port)) { -+ phylink_stop(port->phylink); -+ phylink_disconnect_phy(port->phylink); -+ } -+ - return 0; - } - -@@ -2916,6 +2938,11 @@ static const struct ethtool_ops airoha_e - .get_link = ethtool_op_get_link, - }; - -+static void airoha_mac_config(struct phylink_config *config, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+} -+ - static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port) - { - int i; -@@ -2960,6 +2987,119 @@ bool airoha_is_valid_gdm_port(struct air - return false; - } - -+static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port, -+ phylink_config); -+ struct airoha_qdma *qdma = port->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ u32 frag_size_tx, frag_size_rx; -+ -+ if (port->id != 4) -+ return; -+ -+ switch (speed) { -+ case SPEED_10000: -+ case SPEED_5000: -+ frag_size_tx = 8; -+ frag_size_rx = 8; -+ break; -+ case SPEED_2500: -+ frag_size_tx = 2; -+ frag_size_rx = 1; -+ break; -+ default: -+ frag_size_tx = 1; -+ frag_size_rx = 0; -+ } -+ -+ /* Configure TX/RX frag based on speed */ -+ airoha_fe_rmw(eth, REG_GDMA4_TMBI_FRAG, -+ GDMA4_SGMII0_TX_FRAG_SIZE_MASK, -+ FIELD_PREP(GDMA4_SGMII0_TX_FRAG_SIZE_MASK, -+ frag_size_tx)); -+ -+ airoha_fe_rmw(eth, REG_GDMA4_RMBI_FRAG, -+ GDMA4_SGMII0_RX_FRAG_SIZE_MASK, -+ FIELD_PREP(GDMA4_SGMII0_RX_FRAG_SIZE_MASK, -+ frag_size_rx)); -+} -+ -+static void airoha_mac_link_down(struct phylink_config *config, unsigned int mode, -+ phy_interface_t interface) -+{ -+} -+ -+static const struct phylink_mac_ops airoha_phylink_ops = { -+ .mac_config = airoha_mac_config, -+ .mac_link_up = airoha_mac_link_up, -+ .mac_link_down = airoha_mac_link_down, -+}; -+ -+static int airoha_fill_available_pcs(struct phylink_config *config, -+ struct phylink_pcs **available_pcs, -+ unsigned int num_available_pcs) -+{ -+ struct device *dev = config->dev; -+ -+ return fwnode_phylink_pcs_parse(dev_fwnode(dev), available_pcs, -+ &num_available_pcs); -+} -+ -+static int airoha_setup_phylink(struct net_device *dev) -+{ -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct device_node *np = dev->dev.of_node; -+ phy_interface_t phy_mode; -+ struct phylink *phylink; -+ int err; -+ -+ err = of_get_phy_mode(np, &phy_mode); -+ if (err) { -+ dev_err(&dev->dev, "incorrect phy-mode\n"); -+ return err; -+ } -+ -+ port->phylink_config.dev = &dev->dev; -+ port->phylink_config.type = PHYLINK_NETDEV; -+ port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -+ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD | -+ MAC_5000FD | MAC_10000FD; -+ -+ err = fwnode_phylink_pcs_parse(dev_fwnode(&dev->dev), NULL, -+ &port->phylink_config.num_available_pcs); -+ if (err) -+ return err; -+ -+ port->phylink_config.fill_available_pcs = airoha_fill_available_pcs; -+ -+ __set_bit(PHY_INTERFACE_MODE_SGMII, -+ port->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, -+ port->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, -+ port->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_10GBASER, -+ port->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_USXGMII, -+ port->phylink_config.supported_interfaces); -+ -+ phy_interface_copy(port->phylink_config.pcs_interfaces, -+ port->phylink_config.supported_interfaces); -+ -+ phylink = phylink_create(&port->phylink_config, -+ of_fwnode_handle(np), -+ phy_mode, &airoha_phylink_ops); -+ if (IS_ERR(phylink)) -+ return PTR_ERR(phylink); -+ -+ port->phylink = phylink; -+ -+ return err; -+} -+ - static int airoha_alloc_gdm_port(struct airoha_eth *eth, - struct device_node *np) - { -@@ -3033,6 +3173,12 @@ static int airoha_alloc_gdm_port(struct - port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; - eth->ports[p] = port; - -+ if (airhoa_is_phy_external(port)) { -+ err = airoha_setup_phylink(dev); -+ if (err) -+ return err; -+ } -+ - return airoha_metadata_dst_alloc(port); - } - -@@ -3160,8 +3306,11 @@ error_napi_stop: - if (!port) - continue; - -- if (port->dev->reg_state == NETREG_REGISTERED) -+ if (port->dev->reg_state == NETREG_REGISTERED) { -+ if (airhoa_is_phy_external(port)) -+ phylink_destroy(port->phylink); - unregister_netdev(port->dev); -+ } - airoha_metadata_dst_free(port); - } - airoha_hw_cleanup(eth); -@@ -3186,6 +3335,8 @@ static void airoha_remove(struct platfor - if (!port) - continue; - -+ if (airhoa_is_phy_external(port)) -+ phylink_destroy(port->phylink); - unregister_netdev(port->dev); - airoha_metadata_dst_free(port); - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -542,6 +542,9 @@ struct airoha_gdm_port { - int id; - int nbq; - -+ struct phylink *phylink; -+ struct phylink_config phylink_config; -+ - struct airoha_hw_stats stats; - - DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -358,6 +358,18 @@ - #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) - #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) - -+#define REG_GDMA4_TMBI_FRAG 0x2028 -+#define GDMA4_SGMII1_TX_WEIGHT_MASK GENMASK(31, 26) -+#define GDMA4_SGMII1_TX_FRAG_SIZE_MASK GENMASK(25, 16) -+#define GDMA4_SGMII0_TX_WEIGHT_MASK GENMASK(15, 10) -+#define GDMA4_SGMII0_TX_FRAG_SIZE_MASK GENMASK(9, 0) -+ -+#define REG_GDMA4_RMBI_FRAG 0x202c -+#define GDMA4_SGMII1_RX_WEIGHT_MASK GENMASK(31, 26) -+#define GDMA4_SGMII1_RX_FRAG_SIZE_MASK GENMASK(25, 16) -+#define GDMA4_SGMII0_RX_WEIGHT_MASK GENMASK(15, 10) -+#define GDMA4_SGMII0_RX_FRAG_SIZE_MASK GENMASK(9, 0) -+ - #define REG_MC_VLAN_EN 0x2100 - #define MC_VLAN_EN_MASK BIT(0) - diff --git a/target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch b/target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch deleted file mode 100644 index bca3d7b3f10..00000000000 --- a/target/linux/airoha/patches-6.12/401-02-v6.16-net-dsa-mt7530-Add-AN7583-support.patch +++ /dev/null @@ -1,143 +0,0 @@ -From d76556db10bf41cd3ae1ad1d705245afe077a701 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 22 May 2025 18:53:10 +0200 -Subject: [PATCH 2/3] net: dsa: mt7530: Add AN7583 support - -Add Airoha AN7583 Switch support. This is based on Airoha EN7581 that is -based on Mediatek MT7988 Switch. - -Airoha AN7583 require additional tweak to the GEPHY_CONN_CFG register to -make the internal PHY work. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://patch.msgid.link/20250522165313.6411-3-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530-mmio.c | 1 + - drivers/net/dsa/mt7530.c | 24 ++++++++++++++++++++++-- - drivers/net/dsa/mt7530.h | 18 ++++++++++++++---- - 3 files changed, 37 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mt7530-mmio.c -+++ b/drivers/net/dsa/mt7530-mmio.c -@@ -11,6 +11,7 @@ - #include "mt7530.h" - - static const struct of_device_id mt7988_of_match[] = { -+ { .compatible = "airoha,an7583-switch", .data = &mt753x_table[ID_AN7583], }, - { .compatible = "airoha,en7581-switch", .data = &mt753x_table[ID_EN7581], }, - { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], }, - { /* sentinel */ }, ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1160,7 +1160,7 @@ mt753x_cpu_port_enable(struct dsa_switch - * is affine to the inbound user port. - */ - if (priv->id == ID_MT7531 || priv->id == ID_MT7988 || -- priv->id == ID_EN7581) -+ priv->id == ID_EN7581 || priv->id == ID_AN7583) - mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port))); - - /* CPU port gets connected to all user ports of -@@ -2600,7 +2600,7 @@ mt7531_setup_common(struct dsa_switch *d - mt7530_set(priv, MT753X_AGC, LOCAL_EN); - - /* Enable Special Tag for rx frames */ -- if (priv->id == ID_EN7581) -+ if (priv->id == ID_EN7581 || priv->id == ID_AN7583) - mt7530_write(priv, MT753X_CPORT_SPTAG_CFG, - CPORT_SW2FE_STAG_EN | CPORT_FE2SW_STAG_EN); - -@@ -3168,6 +3168,16 @@ static int mt7988_setup(struct dsa_switc - reset_control_deassert(priv->rstc); - usleep_range(20, 50); - -+ /* AN7583 require additional tweak to CONN_CFG */ -+ if (priv->id == ID_AN7583) -+ mt7530_rmw(priv, AN7583_GEPHY_CONN_CFG, -+ AN7583_CSR_DPHY_CKIN_SEL | -+ AN7583_CSR_PHY_CORE_REG_CLK_SEL | -+ AN7583_CSR_ETHER_AFE_PWD, -+ AN7583_CSR_DPHY_CKIN_SEL | -+ AN7583_CSR_PHY_CORE_REG_CLK_SEL | -+ FIELD_PREP(AN7583_CSR_ETHER_AFE_PWD, 0)); -+ - /* Reset the switch PHYs */ - mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST); - -@@ -3264,6 +3274,16 @@ const struct mt753x_info mt753x_table[] - .pcs_ops = &mt7530_pcs_ops, - .sw_setup = mt7988_setup, - .phy_read_c22 = mt7531_ind_c22_phy_read, -+ .phy_write_c22 = mt7531_ind_c22_phy_write, -+ .phy_read_c45 = mt7531_ind_c45_phy_read, -+ .phy_write_c45 = mt7531_ind_c45_phy_write, -+ .mac_port_get_caps = en7581_mac_port_get_caps, -+ }, -+ [ID_AN7583] = { -+ .id = ID_AN7583, -+ .pcs_ops = &mt7530_pcs_ops, -+ .sw_setup = mt7988_setup, -+ .phy_read_c22 = mt7531_ind_c22_phy_read, - .phy_write_c22 = mt7531_ind_c22_phy_write, - .phy_read_c45 = mt7531_ind_c45_phy_read, - .phy_write_c45 = mt7531_ind_c45_phy_write, ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -20,6 +20,7 @@ enum mt753x_id { - ID_MT7531 = 2, - ID_MT7988 = 3, - ID_EN7581 = 4, -+ ID_AN7583 = 5, - }; - - #define NUM_TRGMII_CTRL 5 -@@ -66,7 +67,8 @@ enum mt753x_id { - - #define MT753X_MIRROR_REG(id) ((id == ID_MT7531 || \ - id == ID_MT7988 || \ -- id == ID_EN7581) ? \ -+ id == ID_EN7581 || \ -+ id == ID_AN7583) ? \ - MT7531_CFC : MT753X_MFC) - - #define MT753X_MIRROR_EN(id) ((id == ID_MT7531 || \ -@@ -76,19 +78,22 @@ enum mt753x_id { - - #define MT753X_MIRROR_PORT_MASK(id) ((id == ID_MT7531 || \ - id == ID_MT7988 || \ -- id == ID_EN7581) ? \ -+ id == ID_EN7581 || \ -+ id == ID_AN7583) ? \ - MT7531_MIRROR_PORT_MASK : \ - MT7530_MIRROR_PORT_MASK) - - #define MT753X_MIRROR_PORT_GET(id, val) ((id == ID_MT7531 || \ - id == ID_MT7988 || \ -- id == ID_EN7581) ? \ -+ id == ID_EN7581 || \ -+ id == ID_AN7583) ? \ - MT7531_MIRROR_PORT_GET(val) : \ - MT7530_MIRROR_PORT_GET(val)) - - #define MT753X_MIRROR_PORT_SET(id, val) ((id == ID_MT7531 || \ - id == ID_MT7988 || \ -- id == ID_EN7581) ? \ -+ id == ID_EN7581 || \ -+ id == ID_AN7583) ? \ - MT7531_MIRROR_PORT_SET(val) : \ - MT7530_MIRROR_PORT_SET(val)) - -@@ -619,6 +624,11 @@ enum mt7531_xtal_fsel { - #define CPORT_SW2FE_STAG_EN BIT(1) - #define CPORT_FE2SW_STAG_EN BIT(0) - -+#define AN7583_GEPHY_CONN_CFG 0x7c14 -+#define AN7583_CSR_DPHY_CKIN_SEL BIT(31) -+#define AN7583_CSR_PHY_CORE_REG_CLK_SEL BIT(30) -+#define AN7583_CSR_ETHER_AFE_PWD GENMASK(28, 24) -+ - /* Registers for LED GPIO control (MT7530 only) - * All registers follow this pattern: - * [ 2: 0] port 0 diff --git a/target/linux/airoha/patches-6.12/402-01-thermal-airoha-convert-to-regmap-API.patch b/target/linux/airoha/patches-6.12/402-01-thermal-airoha-convert-to-regmap-API.patch deleted file mode 100644 index 9414bef9cbc..00000000000 --- a/target/linux/airoha/patches-6.12/402-01-thermal-airoha-convert-to-regmap-API.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 7d55e75edc87022a4c1820588f70a80cebb13c5f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 23 May 2025 19:34:54 +0200 -Subject: [PATCH 1/5] thermal: airoha: convert to regmap API - -In preparation for support of Airoha AN7583, convert the driver to -regmap API. This is needed as Airoha AN7583 will be based on syscon -regmap. - -Signed-off-by: Christian Marangi ---- - drivers/thermal/airoha_thermal.c | 72 +++++++++++++++++++------------- - 1 file changed, 42 insertions(+), 30 deletions(-) - ---- a/drivers/thermal/airoha_thermal.c -+++ b/drivers/thermal/airoha_thermal.c -@@ -194,7 +194,7 @@ - #define AIROHA_MAX_SAMPLES 6 - - struct airoha_thermal_priv { -- void __iomem *base; -+ struct regmap *map; - struct regmap *chip_scu; - struct resource scu_adc_res; - -@@ -265,8 +265,8 @@ static int airoha_thermal_set_trips(stru - RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); - - /* We offset the high temp of 1°C to trigger correct event */ -- writel(TEMP_TO_RAW(priv, high) >> 4, -- priv->base + EN7581_TEMPOFFSETH); -+ regmap_write(priv->map, EN7581_TEMPOFFSETH, -+ TEMP_TO_RAW(priv, high) >> 4); - - enable_monitor = true; - } -@@ -277,15 +277,15 @@ static int airoha_thermal_set_trips(stru - RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK))); - - /* We offset the low temp of 1°C to trigger correct event */ -- writel(TEMP_TO_RAW(priv, low) >> 4, -- priv->base + EN7581_TEMPOFFSETL); -+ regmap_write(priv->map, EN7581_TEMPOFFSETL, -+ TEMP_TO_RAW(priv, high) >> 4); - - enable_monitor = true; - } - - /* Enable sensor 0 monitor after trip are set */ - if (enable_monitor) -- writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0); -+ regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN); - - return 0; - } -@@ -302,7 +302,7 @@ static irqreturn_t airoha_thermal_irq(in - bool update = false; - u32 status; - -- status = readl(priv->base + EN7581_TEMPMONINTSTS); -+ regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status); - switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) { - case EN7581_HOFSINTSTS0: - event = THERMAL_TRIP_VIOLATED; -@@ -318,7 +318,7 @@ static irqreturn_t airoha_thermal_irq(in - } - - /* Reset Interrupt */ -- writel(status, priv->base + EN7581_TEMPMONINTSTS); -+ regmap_write(priv->map, EN7581_TEMPMONINTSTS, status); - - if (update) - thermal_zone_device_update(priv->tz, event); -@@ -336,11 +336,11 @@ static void airoha_thermal_setup_adc_val - /* sleep 10 ms for ADC to enable */ - usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); - -- efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG); -+ regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info); - if (efuse_calib_info) { - priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info); - /* Different slope are applied if the sensor is used for CPU or for package */ -- cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG); -+ regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor); - if (cpu_sensor) { - priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT; - priv->init_temp = EN7581_INIT_TEMP_FTK_X10; -@@ -359,8 +359,8 @@ static void airoha_thermal_setup_adc_val - static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) - { - /* Set measure mode */ -- writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4), -- priv->base + EN7581_TEMPMSRCTL0); -+ regmap_write(priv->map, EN7581_TEMPMSRCTL0, -+ FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4)); - - /* - * Configure ADC valid reading addr -@@ -375,15 +375,15 @@ static void airoha_thermal_setup_monitor - * We set valid instead of volt as we don't enable valid/volt - * split reading and AHB read valid addr in such case. - */ -- writel(priv->scu_adc_res.start + EN7581_DOUT_TADC, -- priv->base + EN7581_TEMPADCVALIDADDR); -+ regmap_write(priv->map, EN7581_TEMPADCVALIDADDR, -+ priv->scu_adc_res.start + EN7581_DOUT_TADC); - - /* - * Configure valid bit on a fake value of bit 16. The ADC outputs - * max of 2 bytes for voltage. - */ -- writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16), -- priv->base + EN7581_TEMPADCVALIDMASK); -+ regmap_write(priv->map, EN7581_TEMPADCVALIDMASK, -+ FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16)); - - /* - * AHB supports max 12 bytes for ADC voltage. Shift the read -@@ -391,40 +391,52 @@ static void airoha_thermal_setup_monitor - * in the order of half a °C and is acceptable in the context - * of triggering interrupt in critical condition. - */ -- writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4), -- priv->base + EN7581_TEMPADCVOLTAGESHIFT); -+ regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT, -+ FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4)); - - /* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */ -- writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3), -- priv->base + EN7581_TEMPMONCTL1); -+ regmap_write(priv->map, EN7581_TEMPMONCTL1, -+ FIELD_PREP(EN7581_PERIOD_UNIT, 3)); - - /* - * filt interval is 1 * 52.715us = 52.715us, - * sen interval is 379 * 52.715us = 19.97ms - */ -- writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) | -- FIELD_PREP(EN7581_FILT_INTERVAL, 379), -- priv->base + EN7581_TEMPMONCTL2); -+ regmap_write(priv->map, EN7581_TEMPMONCTL2, -+ FIELD_PREP(EN7581_FILT_INTERVAL, 1) | -+ FIELD_PREP(EN7581_FILT_INTERVAL, 379)); - - /* AHB poll is set to 146 * 68.64 = 10.02us */ -- writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146), -- priv->base + EN7581_TEMPAHBPOLL); -+ regmap_write(priv->map, EN7581_TEMPAHBPOLL, -+ FIELD_PREP(EN7581_ADC_POLL_INTVL, 146)); - } - -+static const struct regmap_config airoha_thermal_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+}; -+ - static int airoha_thermal_probe(struct platform_device *pdev) - { - struct airoha_thermal_priv *priv; - struct device_node *chip_scu_np; - struct device *dev = &pdev->dev; -+ void __iomem *base; - int irq, ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - -- priv->base = devm_platform_ioremap_resource(pdev, 0); -- if (IS_ERR(priv->base)) -- return PTR_ERR(priv->base); -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ priv->map = devm_regmap_init_mmio(dev, base, -+ &airoha_thermal_regmap_config); -+ if (IS_ERR(priv->map)) -+ return PTR_ERR(priv->map); - - chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0); - if (!chip_scu_np) -@@ -462,8 +474,8 @@ static int airoha_thermal_probe(struct p - platform_set_drvdata(pdev, priv); - - /* Enable LOW and HIGH interrupt */ -- writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0, -- priv->base + EN7581_TEMPMONINT); -+ regmap_write(priv->map, EN7581_TEMPMONINT, -+ EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0); - - return 0; - } diff --git a/target/linux/airoha/patches-6.12/402-02-thermal-drivers-airoha-Generalize-probe-function.patch b/target/linux/airoha/patches-6.12/402-02-thermal-drivers-airoha-Generalize-probe-function.patch deleted file mode 100644 index b306b2308b1..00000000000 --- a/target/linux/airoha/patches-6.12/402-02-thermal-drivers-airoha-Generalize-probe-function.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 6c0f01b16687dc582f0470a5d5b20084fb3a290f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 23 May 2025 19:48:32 +0200 -Subject: [PATCH 2/5] thermal/drivers: airoha: Generalize probe function - -In preparation for support of Airoha AN7583, generalize the probe -function to address for the 2 SoC differece. - -Implement a match_data struct where it's possible to define a more -specific probe and post_probe function and specific thermal ops and -pllrg protect value. - -Signed-off-by: Christian Marangi ---- - drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++-------- - 1 file changed, 75 insertions(+), 27 deletions(-) - ---- a/drivers/thermal/airoha_thermal.c -+++ b/drivers/thermal/airoha_thermal.c -@@ -198,12 +198,23 @@ struct airoha_thermal_priv { - struct regmap *chip_scu; - struct resource scu_adc_res; - -+ u32 pllrg_protect; -+ - struct thermal_zone_device *tz; - int init_temp; - int default_slope; - int default_offset; - }; - -+struct airoha_thermal_soc_data { -+ u32 pllrg_protect; -+ -+ const struct thermal_zone_device_ops *thdev_ops; -+ int (*probe)(struct platform_device *pdev, -+ struct airoha_thermal_priv *priv); -+ int (*post_probe)(struct platform_device *pdev); -+}; -+ - static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv) - { - u32 val; -@@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode - regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg); - - /* Give access to thermal regs */ -- regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY); -+ regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, -+ priv->pllrg_protect); - adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1); - regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux); - -@@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode - regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg); - } - --static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp) -+static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp) - { - struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); - int min_value, max_value, avg_value, value; -@@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struc - return 0; - } - --static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low, -+static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low, - int high) - { - struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); -@@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(stru - return 0; - } - --static const struct thermal_zone_device_ops thdev_ops = { -- .get_temp = airoha_thermal_get_temp, -- .set_trips = airoha_thermal_set_trips, -+static const struct thermal_zone_device_ops en7581_thdev_ops = { -+ .get_temp = en7581_thermal_get_temp, -+ .set_trips = en7581_thermal_set_trips, - }; - --static irqreturn_t airoha_thermal_irq(int irq, void *data) -+static irqreturn_t en7581_thermal_irq(int irq, void *data) - { - struct airoha_thermal_priv *priv = data; - enum thermal_notify_event event; -@@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(in - return IRQ_HANDLED; - } - --static void airoha_thermal_setup_adc_val(struct device *dev, -+static void en7581_thermal_setup_adc_val(struct device *dev, - struct airoha_thermal_priv *priv) - { - u32 efuse_calib_info, cpu_sensor; -@@ -356,7 +368,7 @@ static void airoha_thermal_setup_adc_val - } - } - --static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv) -+static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv) - { - /* Set measure mode */ - regmap_write(priv->map, EN7581_TEMPMSRCTL0, -@@ -411,30 +423,26 @@ static void airoha_thermal_setup_monitor - FIELD_PREP(EN7581_ADC_POLL_INTVL, 146)); - } - --static const struct regmap_config airoha_thermal_regmap_config = { -+static const struct regmap_config en7581_thermal_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - }; - --static int airoha_thermal_probe(struct platform_device *pdev) -+static int en7581_thermal_probe(struct platform_device *pdev, -+ struct airoha_thermal_priv *priv) - { -- struct airoha_thermal_priv *priv; - struct device_node *chip_scu_np; - struct device *dev = &pdev->dev; - void __iomem *base; - int irq, ret; - -- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - - priv->map = devm_regmap_init_mmio(dev, base, -- &airoha_thermal_regmap_config); -+ &en7581_thermal_regmap_config); - if (IS_ERR(priv->map)) - return PTR_ERR(priv->map); - -@@ -454,18 +462,55 @@ static int airoha_thermal_probe(struct p - return irq; - - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -- airoha_thermal_irq, IRQF_ONESHOT, -+ en7581_thermal_irq, IRQF_ONESHOT, - pdev->name, priv); - if (ret) { - dev_err(dev, "Can't get interrupt working.\n"); - return ret; - } - -- airoha_thermal_setup_monitor(priv); -- airoha_thermal_setup_adc_val(dev, priv); -+ en7581_thermal_setup_monitor(priv); -+ en7581_thermal_setup_adc_val(dev, priv); -+ -+ return 0; -+} -+ -+static int en7581_thermal_post_probe(struct platform_device *pdev) -+{ -+ struct airoha_thermal_priv *priv = platform_get_drvdata(pdev); -+ -+ /* Enable LOW and HIGH interrupt (if supported) */ -+ regmap_write(priv->map, EN7581_TEMPMONINT, -+ EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0); -+ -+ return 0; -+} -+ -+static int airoha_thermal_probe(struct platform_device *pdev) -+{ -+ const struct airoha_thermal_soc_data *soc_data; -+ struct airoha_thermal_priv *priv; -+ struct device *dev = &pdev->dev; -+ int ret; -+ -+ soc_data = device_get_match_data(dev); -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->pllrg_protect = soc_data->pllrg_protect; -+ -+ if (!soc_data->probe) -+ return -EINVAL; -+ -+ ret = soc_data->probe(pdev, priv); -+ if (ret) -+ return ret; - - /* register of thermal sensor and get info from DT */ -- priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops); -+ priv->tz = devm_thermal_of_zone_register(dev, 0, priv, -+ soc_data->thdev_ops); - if (IS_ERR(priv->tz)) { - dev_err(dev, "register thermal zone sensor failed\n"); - return PTR_ERR(priv->tz); -@@ -473,15 +518,18 @@ static int airoha_thermal_probe(struct p - - platform_set_drvdata(pdev, priv); - -- /* Enable LOW and HIGH interrupt */ -- regmap_write(priv->map, EN7581_TEMPMONINT, -- EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0); -- -- return 0; -+ return soc_data->post_probe ? soc_data->post_probe(pdev) : 0; - } - -+static const struct airoha_thermal_soc_data en7581_data = { -+ .pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY, -+ .thdev_ops = &en7581_thdev_ops, -+ .probe = &en7581_thermal_probe, -+ .post_probe = &en7581_thermal_post_probe, -+}; -+ - static const struct of_device_id airoha_thermal_match[] = { -- { .compatible = "airoha,en7581-thermal" }, -+ { .compatible = "airoha,en7581-thermal", .data = &en7581_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, airoha_thermal_match); diff --git a/target/linux/airoha/patches-6.12/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch b/target/linux/airoha/patches-6.12/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch deleted file mode 100644 index 5f6ae2c08a8..00000000000 --- a/target/linux/airoha/patches-6.12/402-03-thermal-drivers-airoha-generalize-get_thermal_ADC-an.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 1e623852d07759c3c076505193bd7f0bd3486774 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 23 May 2025 19:54:53 +0200 -Subject: [PATCH 3/5] thermal/drivers: airoha: generalize get_thermal_ADC and - set_mux function - -In preparation for support of Airoha AN7583, generalize -get_thermal_ADC() and set_thermal_mux() with the use of reg_field API. - -This is to account the same logic between the current supported SoC and -the new one but with different register address. - -While at it also further improve some comments and move sleep inside the -set_thermal_mux function. - -Signed-off-by: Christian Marangi ---- - drivers/thermal/airoha_thermal.c | 54 +++++++++++++++++++++++++------- - 1 file changed, 42 insertions(+), 12 deletions(-) - ---- a/drivers/thermal/airoha_thermal.c -+++ b/drivers/thermal/airoha_thermal.c -@@ -193,9 +193,18 @@ - - #define AIROHA_MAX_SAMPLES 6 - -+enum airoha_thermal_chip_scu_field { -+ AIROHA_THERMAL_DOUT_TADC, -+ AIROHA_THERMAL_MUX_TADC, -+ -+ /* keep last */ -+ AIROHA_THERMAL_FIELD_MAX, -+}; -+ - struct airoha_thermal_priv { - struct regmap *map; - struct regmap *chip_scu; -+ struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX]; - struct resource scu_adc_res; - - u32 pllrg_protect; -@@ -219,22 +228,29 @@ static int airoha_get_thermal_ADC(struct - { - u32 val; - -- regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val); -- return FIELD_GET(EN7581_DOUT_TADC_MASK, val); -+ regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC], -+ &val); -+ return val; - } - --static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv) -+static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv, -+ int tdac_idx) - { -- u32 adc_mux, pllrg; -+ u32 pllrg; - - /* Save PLLRG current value */ - regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg); - -- /* Give access to thermal regs */ -+ /* Give access to Thermal regs */ - regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, - priv->pllrg_protect); -- adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1); -- regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux); -+ -+ /* Configure Thermal ADC mux to tdac_idx */ -+ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC], -+ tdac_idx); -+ -+ /* Sleep 10 ms for Thermal ADC to enable */ -+ usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); - - /* Restore PLLRG value on exit */ - regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg); -@@ -343,10 +359,8 @@ static void en7581_thermal_setup_adc_val - { - u32 efuse_calib_info, cpu_sensor; - -- /* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */ -- airoha_init_thermal_ADC_mode(priv); -- /* sleep 10 ms for ADC to enable */ -- usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); -+ /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */ -+ airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1); - - regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info); - if (efuse_calib_info) { -@@ -429,13 +443,18 @@ static const struct regmap_config en7581 - .val_bits = 32, - }; - -+static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = { -+ [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15), -+ [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3), -+}; -+ - static int en7581_thermal_probe(struct platform_device *pdev, - struct airoha_thermal_priv *priv) - { - struct device_node *chip_scu_np; - struct device *dev = &pdev->dev; - void __iomem *base; -- int irq, ret; -+ int i, irq, ret; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) -@@ -454,6 +473,17 @@ static int en7581_thermal_probe(struct p - if (IS_ERR(priv->chip_scu)) - return PTR_ERR(priv->chip_scu); - -+ for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) { -+ struct regmap_field *field; -+ -+ field = devm_regmap_field_alloc(dev, priv->chip_scu, -+ en7581_chip_scu_fields[i]); -+ if (IS_ERR(field)) -+ return PTR_ERR(field); -+ -+ priv->chip_scu_fields[i] = field; -+ } -+ - of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res); - of_node_put(chip_scu_np); - diff --git a/target/linux/airoha/patches-6.12/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch b/target/linux/airoha/patches-6.12/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch deleted file mode 100644 index 51332350ef7..00000000000 --- a/target/linux/airoha/patches-6.12/402-05-thermal-drivers-airoha-Add-support-for-AN7583.patch +++ /dev/null @@ -1,277 +0,0 @@ -From 5891a9e5fbdf9a305b5f81e2625455efb2a886f0 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 23 May 2025 19:59:20 +0200 -Subject: [PATCH 5/5] thermal/drivers: airoha: Add support for AN7583 - -Add support for Airoha AN7583 Thermal driver. This apply similar logic -on how to read the temperature but totally drop support for the -PTP_THERMAL subsystem. PTP_THERMAL subsystem was a way to trigger trip -point from hardware by configuring how to read the temperature -internally. - -This subsystem has been totally removed from Airoha AN7583 permitting -only to read the temperature. - -The SoC support up to 3 sensor but the original driver always read the -BGA sensor hence it's currently implemented reading only this specific -sensor. Reference and values for the other 2 sensor are defined for -further implementation if confirmed working. - -set_thermal_mux() is extended to also address muxing the sensor as -AN7583 use a different way to read the temperature from 3 different -diode. The EN7581 code is updated to account for these changes. - -Signed-off-by: Christian Marangi ---- - drivers/thermal/airoha_thermal.c | 158 ++++++++++++++++++++++++++++++- - 1 file changed, 154 insertions(+), 4 deletions(-) - ---- a/drivers/thermal/airoha_thermal.c -+++ b/drivers/thermal/airoha_thermal.c -@@ -18,6 +18,12 @@ - #define EN7581_DOUT_TADC 0x2f8 - #define EN7581_DOUT_TADC_MASK GENMASK(15, 0) - -+#define AN7583_MUX_SENSOR 0x2a0 -+#define AN7583_LOAD_ADJ GENMASK(3, 2) -+#define AN7583_MUX_TADC 0x2e4 -+#define AN7583_MUX_TADC_MASK GENMASK(3, 1) -+#define AN7583_DOUT_TADC 0x2f0 -+ - /* PTP_THERMAL regs */ - #define EN7581_TEMPMONCTL0 0x800 - #define EN7581_SENSE3_EN BIT(3) -@@ -181,6 +187,11 @@ - #define EN7581_SCU_THERMAL_PROTECT_KEY 0x12 - #define EN7581_SCU_THERMAL_MUX_DIODE1 0x7 - -+#define AN7583_SCU_THERMAL_PROTECT_KEY 0x80 -+#define AN7583_NUM_SENSOR 3 -+ -+#define AIROHA_THERMAL_NO_MUX_SENSOR -1 -+ - /* Convert temp to raw value as read from ADC ((((temp / 100) - init) * slope) / 1000) + offset */ - #define TEMP_TO_RAW(priv, temp) ((((((temp) / 100) - (priv)->init_temp) * \ - (priv)->default_slope) / 1000) + \ -@@ -193,8 +204,39 @@ - - #define AIROHA_MAX_SAMPLES 6 - -+/* -+ * AN7583 supports all these ADC mux but the original driver -+ * always checked temp with the AN7583_BGP_TEMP_SENSOR. -+ * Assume using the other sensor temperature is invalid and -+ * always read from AN7583_BGP_TEMP_SENSOR. -+ * -+ * On top of this it's defined that AN7583 supports 3 -+ * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR, -+ * AN7583_CPU_TEMP_SENSOR. -+ * -+ * Provide the ADC mux for reference. -+ */ -+enum an7583_thermal_adc_mux { -+ AN7583_BGP_TEMP_SENSOR, -+ AN7583_PAD_AVS, -+ AN7583_CORE_POWER, -+ AN7583_AVSDAC_OUT, -+ AN7583_VCM, -+ AN7583_GBE_TEMP_SENSOR, -+ AN7583_CPU_TEMP_SENSOR, -+ -+ AN7583_ADC_MUX_MAX, -+}; -+ -+enum an7583_thermal_diode_mux { -+ AN7583_D0_TADC, -+ AN7583_ZERO_TADC, -+ AN7583_D1_TADC, -+}; -+ - enum airoha_thermal_chip_scu_field { - AIROHA_THERMAL_DOUT_TADC, -+ AIROHA_THERMAL_MUX_SENSOR, - AIROHA_THERMAL_MUX_TADC, - - /* keep last */ -@@ -208,6 +250,7 @@ struct airoha_thermal_priv { - struct resource scu_adc_res; - - u32 pllrg_protect; -+ int current_adc; - - struct thermal_zone_device *tz; - int init_temp; -@@ -224,6 +267,24 @@ struct airoha_thermal_soc_data { - int (*post_probe)(struct platform_device *pdev); - }; - -+static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = { -+ [AN7583_BGP_TEMP_SENSOR] = 973, -+ [AN7583_GBE_TEMP_SENSOR] = 995, -+ [AN7583_CPU_TEMP_SENSOR] = 1035, -+}; -+ -+static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = { -+ [AN7583_BGP_TEMP_SENSOR] = 7440, -+ [AN7583_GBE_TEMP_SENSOR] = 7620, -+ [AN7583_CPU_TEMP_SENSOR] = 8390, -+}; -+ -+static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = { -+ [AN7583_BGP_TEMP_SENSOR] = 294, -+ [AN7583_GBE_TEMP_SENSOR] = 298, -+ [AN7583_CPU_TEMP_SENSOR] = 344, -+}; -+ - static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv) - { - u32 val; -@@ -234,7 +295,7 @@ static int airoha_get_thermal_ADC(struct - } - - static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv, -- int tdac_idx) -+ int tdac_idx, int sensor_idx) - { - u32 pllrg; - -@@ -245,9 +306,20 @@ static void airoha_set_thermal_mux(struc - regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, - priv->pllrg_protect); - -+ /* -+ * Configure Thermal Sensor mux to sensor_idx. -+ * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR) -+ */ -+ if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR) -+ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR], -+ sensor_idx); -+ - /* Configure Thermal ADC mux to tdac_idx */ -- regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC], -- tdac_idx); -+ if (priv->current_adc != tdac_idx) { -+ regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC], -+ tdac_idx); -+ priv->current_adc = tdac_idx; -+ } - - /* Sleep 10 ms for Thermal ADC to enable */ - usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC); -@@ -360,7 +432,8 @@ static void en7581_thermal_setup_adc_val - u32 efuse_calib_info, cpu_sensor; - - /* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */ -- airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1); -+ airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1, -+ AIROHA_THERMAL_NO_MUX_SENSOR); - - regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info); - if (efuse_calib_info) { -@@ -476,6 +549,10 @@ static int en7581_thermal_probe(struct p - for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) { - struct regmap_field *field; - -+ /* Skip registering MUX_SENSOR field as not supported */ -+ if (i == AIROHA_THERMAL_MUX_SENSOR) -+ continue; -+ - field = devm_regmap_field_alloc(dev, priv->chip_scu, - en7581_chip_scu_fields[i]); - if (IS_ERR(field)) -@@ -516,6 +593,71 @@ static int en7581_thermal_post_probe(str - return 0; - } - -+static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp) -+{ -+ struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz); -+ int sensor_idx; -+ int delta_diode, delta_gain; -+ int coeff, slope, offset; -+ -+ int diode_zero, diode_d0, diode_d1; -+ -+ /* Always read sensor AN7583_BGP_TEMP_SENSOR */ -+ sensor_idx = AN7583_BGP_TEMP_SENSOR; -+ -+ coeff = an7583_thermal_coeff[sensor_idx]; -+ slope = an7583_thermal_slope[sensor_idx]; -+ offset = an7583_thermal_offset[sensor_idx]; -+ -+ airoha_set_thermal_mux(priv, sensor_idx, AN7583_ZERO_TADC); -+ diode_zero = airoha_get_thermal_ADC(priv); -+ airoha_set_thermal_mux(priv, sensor_idx, AN7583_D0_TADC); -+ diode_d0 = airoha_get_thermal_ADC(priv); -+ airoha_set_thermal_mux(priv, sensor_idx, AN7583_D1_TADC); -+ diode_d1 = airoha_get_thermal_ADC(priv); -+ -+ delta_diode = diode_d1 - diode_d0; -+ delta_gain = (delta_diode * coeff) / 100 + (diode_zero - diode_d1); -+ *temp = (slope * delta_diode * 10) / delta_gain - offset * 10; -+ *temp *= 100; -+ -+ return 0; -+} -+ -+static const struct thermal_zone_device_ops an7583_tz_ops = { -+ .get_temp = an7583_thermal_get_temp, -+}; -+ -+static const struct reg_field an7583_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = { -+ [AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(AN7583_DOUT_TADC, 0, 31), -+ [AIROHA_THERMAL_MUX_TADC] = REG_FIELD(AN7583_MUX_TADC, 1, 3), -+ [AIROHA_THERMAL_MUX_SENSOR] = REG_FIELD(AN7583_MUX_SENSOR, 2, 3), -+}; -+ -+static int an7583_thermal_probe(struct platform_device *pdev, -+ struct airoha_thermal_priv *priv) -+{ -+ struct device *dev = &pdev->dev; -+ int i; -+ -+ priv->chip_scu = device_node_to_regmap(dev->parent->of_node); -+ if (IS_ERR(priv->map)) -+ return PTR_ERR(priv->map); -+ -+ for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) { -+ struct regmap_field *field; -+ -+ field = devm_regmap_field_alloc(dev, priv->chip_scu, -+ an7583_chip_scu_fields[i]); -+ if (IS_ERR(field)) -+ return PTR_ERR(field); -+ -+ priv->chip_scu_fields[i] = field; -+ } -+ -+ return 0; -+} -+ - static int airoha_thermal_probe(struct platform_device *pdev) - { - const struct airoha_thermal_soc_data *soc_data; -@@ -530,6 +672,7 @@ static int airoha_thermal_probe(struct p - return -ENOMEM; - - priv->pllrg_protect = soc_data->pllrg_protect; -+ priv->current_adc = -1; - - if (!soc_data->probe) - return -EINVAL; -@@ -558,8 +701,15 @@ static const struct airoha_thermal_soc_d - .post_probe = &en7581_thermal_post_probe, - }; - -+static const struct airoha_thermal_soc_data an7583_data = { -+ .pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY, -+ .thdev_ops = &an7583_tz_ops, -+ .probe = &an7583_thermal_probe, -+}; -+ - static const struct of_device_id airoha_thermal_match[] = { - { .compatible = "airoha,en7581-thermal", .data = &en7581_data }, -+ { .compatible = "airoha,an7583-thermal", .data = &an7583_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, airoha_thermal_match); diff --git a/target/linux/airoha/patches-6.12/403-v6.18-cpufreq-airoha-Add-support-for-AN7583-SoC.patch b/target/linux/airoha/patches-6.12/403-v6.18-cpufreq-airoha-Add-support-for-AN7583-SoC.patch deleted file mode 100644 index 1b4e2c51ade..00000000000 --- a/target/linux/airoha/patches-6.12/403-v6.18-cpufreq-airoha-Add-support-for-AN7583-SoC.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 8640689f17fd550c3e89d2b47ecb02536c58baf3 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 9 Aug 2025 13:28:30 +0200 -Subject: [PATCH] cpufreq: airoha: Add support for AN7583 SoC - -New Airoha AN7583 SoC use the same exact logic to control the CPU -frequency. Add the Device compatible to the block list for -cpufreq-dt-plat and to the Airoha CPUFreq driver compatible list. - -Signed-off-by: Christian Marangi -Signed-off-by: Viresh Kumar ---- - drivers/cpufreq/airoha-cpufreq.c | 1 + - drivers/cpufreq/cpufreq-dt-platdev.c | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/cpufreq/airoha-cpufreq.c -+++ b/drivers/cpufreq/airoha-cpufreq.c -@@ -121,6 +121,7 @@ static struct platform_driver airoha_cpu - }; - - static const struct of_device_id airoha_cpufreq_match_list[] __initconst = { -+ { .compatible = "airoha,an7583" }, - { .compatible = "airoha,en7581" }, - {}, - }; ---- a/drivers/cpufreq/cpufreq-dt-platdev.c -+++ b/drivers/cpufreq/cpufreq-dt-platdev.c -@@ -104,6 +104,7 @@ static const struct of_device_id allowli - * platforms using "operating-points-v2" property. - */ - static const struct of_device_id blocklist[] __initconst = { -+ { .compatible = "airoha,an7583", }, - { .compatible = "airoha,en7581", }, - - { .compatible = "allwinner,sun50i-h6", }, diff --git a/target/linux/airoha/patches-6.12/600-01-clk-en7523-convert-driver-to-regmap-API.patch b/target/linux/airoha/patches-6.12/600-01-clk-en7523-convert-driver-to-regmap-API.patch deleted file mode 100644 index 85bd2c214e1..00000000000 --- a/target/linux/airoha/patches-6.12/600-01-clk-en7523-convert-driver-to-regmap-API.patch +++ /dev/null @@ -1,351 +0,0 @@ -From 8d5a00b3b83f76d255bcffc91d5263f72b27547a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 7 Feb 2025 23:51:23 +0100 -Subject: [PATCH 01/10] clk: en7523: convert driver to regmap API - -Convert driver to regmap API, in preparation for support of Airoha -AN7523 as the SCU will be an MFD and the regmap will be provided in the -parent node. - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 137 ++++++++++++++++++++++----------------- - 1 file changed, 76 insertions(+), 61 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -1,5 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0-only - -+#include - #include - #include - #include -@@ -34,6 +35,7 @@ - #define REG_RESET_CONTROL_PCIE2 BIT(26) - /* EN7581 */ - #define REG_NP_SCU_PCIC 0x88 -+#define REG_PCIE_CTRL GENMASK(7, 0) - #define REG_NP_SCU_SSTR 0x9c - #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) - #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) -@@ -63,14 +65,14 @@ struct en_clk_desc { - }; - - struct en_clk_gate { -- void __iomem *base; -+ struct regmap *map; - struct clk_hw hw; - }; - - struct en_rst_data { - const u16 *bank_ofs; - const u16 *idx_map; -- void __iomem *base; -+ struct regmap *map; - struct reset_controller_dev rcdev; - }; - -@@ -388,44 +390,44 @@ static u32 en7523_get_div(const struct e - static int en7523_pci_is_enabled(struct clk_hw *hw) - { - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -+ u32 val; - -- return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1); -+ regmap_read(cg->map, REG_PCI_CONTROL, &val); -+ return !!(val & REG_PCI_CONTROL_REFCLK_EN1); - } - - static int en7523_pci_prepare(struct clk_hw *hw) - { - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -- void __iomem *np_base = cg->base; -- u32 val, mask; -+ struct regmap *map = cg->map; -+ u32 mask; - - /* Need to pull device low before reset */ -- val = readl(np_base + REG_PCI_CONTROL); -- val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT); -- writel(val, np_base + REG_PCI_CONTROL); -+ regmap_clear_bits(map, REG_PCI_CONTROL, -+ REG_PCI_CONTROL_PERSTOUT1 | -+ REG_PCI_CONTROL_PERSTOUT); - usleep_range(1000, 2000); - - /* Enable PCIe port 1 */ -- val |= REG_PCI_CONTROL_REFCLK_EN1; -- writel(val, np_base + REG_PCI_CONTROL); -+ regmap_set_bits(map, REG_PCI_CONTROL, -+ REG_PCI_CONTROL_REFCLK_EN1); - usleep_range(1000, 2000); - - /* Reset to default */ -- val = readl(np_base + REG_RESET_CONTROL1); - mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 | - REG_RESET_CONTROL_PCIEHB; -- writel(val & ~mask, np_base + REG_RESET_CONTROL1); -+ regmap_clear_bits(map, REG_RESET_CONTROL1, mask); - usleep_range(1000, 2000); -- writel(val | mask, np_base + REG_RESET_CONTROL1); -+ regmap_set_bits(map, REG_RESET_CONTROL1, mask); - msleep(100); -- writel(val & ~mask, np_base + REG_RESET_CONTROL1); -+ regmap_clear_bits(map, REG_RESET_CONTROL1, mask); - usleep_range(5000, 10000); - - /* Release device */ - mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT; -- val = readl(np_base + REG_PCI_CONTROL); -- writel(val & ~mask, np_base + REG_PCI_CONTROL); -+ regmap_clear_bits(map, REG_PCI_CONTROL, mask); - usleep_range(1000, 2000); -- writel(val | mask, np_base + REG_PCI_CONTROL); -+ regmap_set_bits(map, REG_PCI_CONTROL, mask); - msleep(250); - - return 0; -@@ -434,16 +436,13 @@ static int en7523_pci_prepare(struct clk - static void en7523_pci_unprepare(struct clk_hw *hw) - { - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -- void __iomem *np_base = cg->base; -- u32 val; -+ struct regmap *map = cg->map; - -- val = readl(np_base + REG_PCI_CONTROL); -- val &= ~REG_PCI_CONTROL_REFCLK_EN1; -- writel(val, np_base + REG_PCI_CONTROL); -+ regmap_clear_bits(map, REG_PCI_CONTROL, REG_PCI_CONTROL_REFCLK_EN1); - } - - static struct clk_hw *en7523_register_pcie_clk(struct device *dev, -- void __iomem *np_base) -+ struct regmap *clk_map) - { - const struct en_clk_soc_data *soc_data = device_get_match_data(dev); - struct clk_init_data init = { -@@ -456,7 +455,7 @@ static struct clk_hw *en7523_register_pc - if (!cg) - return NULL; - -- cg->base = np_base; -+ cg->map = clk_map; - cg->hw.init = &init; - - if (init.ops->unprepare) -@@ -474,21 +473,20 @@ static int en7581_pci_is_enabled(struct - u32 val, mask; - - mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; -- val = readl(cg->base + REG_PCI_CONTROL); -+ regmap_read(cg->map, REG_PCI_CONTROL, &val); - return (val & mask) == mask; - } - - static int en7581_pci_enable(struct clk_hw *hw) - { - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -- void __iomem *np_base = cg->base; -- u32 val, mask; -+ struct regmap *map = cg->map; -+ u32 mask; - - mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | - REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | - REG_PCI_CONTROL_PERSTOUT; -- val = readl(np_base + REG_PCI_CONTROL); -- writel(val | mask, np_base + REG_PCI_CONTROL); -+ regmap_set_bits(map, REG_PCI_CONTROL, mask); - - return 0; - } -@@ -496,19 +494,18 @@ static int en7581_pci_enable(struct clk_ - static void en7581_pci_disable(struct clk_hw *hw) - { - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -- void __iomem *np_base = cg->base; -- u32 val, mask; -+ struct regmap *map = cg->map; -+ u32 mask; - - mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | - REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | - REG_PCI_CONTROL_PERSTOUT; -- val = readl(np_base + REG_PCI_CONTROL); -- writel(val & ~mask, np_base + REG_PCI_CONTROL); -+ regmap_clear_bits(map, REG_PCI_CONTROL, mask); - usleep_range(1000, 2000); - } - - static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, -- void __iomem *base, void __iomem *np_base) -+ struct regmap *map, struct regmap *clk_map) - { - struct clk_hw *hw; - u32 rate; -@@ -517,10 +514,12 @@ static void en7523_register_clocks(struc - for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { - const struct en_clk_desc *desc = &en7523_base_clks[i]; - u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; -- u32 val = readl(base + desc->base_reg); -+ u32 val; -+ -+ regmap_read(map, desc->base_reg, &val); - - rate = en7523_get_base_rate(desc, val); -- val = readl(base + reg); -+ regmap_read(map, reg, &val); - rate /= en7523_get_div(desc, val); - - hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); -@@ -533,30 +532,47 @@ static void en7523_register_clocks(struc - clk_data->hws[desc->id] = hw; - } - -- hw = en7523_register_pcie_clk(dev, np_base); -+ hw = en7523_register_pcie_clk(dev, clk_map); - clk_data->hws[EN7523_CLK_PCIE] = hw; - } - -+static const struct regmap_config en7523_clk_regmap_config = { -+ .reg_bits = 32, -+ .val_bits = 32, -+ .reg_stride = 4, -+}; -+ - static int en7523_clk_hw_init(struct platform_device *pdev, - struct clk_hw_onecell_data *clk_data) - { - void __iomem *base, *np_base; -+ struct regmap *map, *clk_map; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) - return PTR_ERR(base); - -+ map = devm_regmap_init_mmio(&pdev->dev, base, -+ &en7523_clk_regmap_config); -+ if (IS_ERR(map)) -+ return PTR_ERR(map); -+ - np_base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(np_base)) - return PTR_ERR(np_base); - -- en7523_register_clocks(&pdev->dev, clk_data, base, np_base); -+ clk_map = devm_regmap_init_mmio(&pdev->dev, np_base, -+ &en7523_clk_regmap_config); -+ if (IS_ERR(clk_map)) -+ return PTR_ERR(clk_map); -+ -+ en7523_register_clocks(&pdev->dev, clk_data, map, clk_map); - - return 0; - } - - static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, -- struct regmap *map, void __iomem *base) -+ struct regmap *map, struct regmap *clk_map) - { - struct clk_hw *hw; - u32 rate; -@@ -593,7 +609,7 @@ static void en7581_register_clocks(struc - clk_data->hws[desc->id] = hw; - } - -- hw = en7523_register_pcie_clk(dev, base); -+ hw = en7523_register_pcie_clk(dev, clk_map); - clk_data->hws[EN7523_CLK_PCIE] = hw; - } - -@@ -601,15 +617,10 @@ static int en7523_reset_update(struct re - unsigned long id, bool assert) - { - struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); -- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; -- u32 val; -+ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; - -- val = readl(addr); -- if (assert) -- val |= BIT(id % RST_NR_PER_BANK); -- else -- val &= ~BIT(id % RST_NR_PER_BANK); -- writel(val, addr); -+ regmap_update_bits(rst_data->map, addr, BIT(id % RST_NR_PER_BANK), -+ assert ? BIT(id % RST_NR_PER_BANK) : 0); - - return 0; - } -@@ -630,9 +641,11 @@ static int en7523_reset_status(struct re - unsigned long id) - { - struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev); -- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK]; -+ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK]; -+ u32 val; - -- return !!(readl(addr) & BIT(id % RST_NR_PER_BANK)); -+ regmap_read(rst_data->map, addr, &val); -+ return !!(val & BIT(id % RST_NR_PER_BANK)); - } - - static int en7523_reset_xlate(struct reset_controller_dev *rcdev, -@@ -652,7 +665,7 @@ static const struct reset_control_ops en - .status = en7523_reset_status, - }; - --static int en7581_reset_register(struct device *dev, void __iomem *base) -+static int en7581_reset_register(struct device *dev, struct regmap *map) - { - struct en_rst_data *rst_data; - -@@ -662,7 +675,7 @@ static int en7581_reset_register(struct - - rst_data->bank_ofs = en7581_rst_ofs; - rst_data->idx_map = en7581_rst_map; -- rst_data->base = base; -+ rst_data->map = map; - - rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); - rst_data->rcdev.of_xlate = en7523_reset_xlate; -@@ -678,9 +691,8 @@ static int en7581_reset_register(struct - static int en7581_clk_hw_init(struct platform_device *pdev, - struct clk_hw_onecell_data *clk_data) - { -- struct regmap *map; -+ struct regmap *map, *clk_map; - void __iomem *base; -- u32 val; - - map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); - if (IS_ERR(map)) -@@ -690,15 +702,18 @@ static int en7581_clk_hw_init(struct pla - if (IS_ERR(base)) - return PTR_ERR(base); - -- en7581_register_clocks(&pdev->dev, clk_data, map, base); -- -- val = readl(base + REG_NP_SCU_SSTR); -- val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); -- writel(val, base + REG_NP_SCU_SSTR); -- val = readl(base + REG_NP_SCU_PCIC); -- writel(val | 3, base + REG_NP_SCU_PCIC); -+ clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config); -+ if (IS_ERR(clk_map)) -+ return PTR_ERR(clk_map); -+ -+ en7581_register_clocks(&pdev->dev, clk_data, map, clk_map); -+ -+ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, -+ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); -+ regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, -+ FIELD_PREP(REG_PCIE_CTRL, 3)); - -- return en7581_reset_register(&pdev->dev, base); -+ return en7581_reset_register(&pdev->dev, clk_map); - } - - static int en7523_clk_probe(struct platform_device *pdev) diff --git a/target/linux/airoha/patches-6.12/600-02-clk-en7523-generalize-register-clocks-function.patch b/target/linux/airoha/patches-6.12/600-02-clk-en7523-generalize-register-clocks-function.patch deleted file mode 100644 index b8d892ffb49..00000000000 --- a/target/linux/airoha/patches-6.12/600-02-clk-en7523-generalize-register-clocks-function.patch +++ /dev/null @@ -1,258 +0,0 @@ -From 36a3a919391dea2000f355125f0a161c453fcf78 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 8 Feb 2025 00:08:08 +0100 -Subject: [PATCH 02/10] clk: en7523: generalize register clocks function - -Generalize register clocks function for Airoha EN7523 and EN7581 clocks -driver. The same logic is applied for both clock hence code can be -reduced and simplified by putting the base_clocks struct in the soc_data -and passing that to a generic register clocks function. - -While at it rework some function to return error and use devm variant -for clk_hw_regiser. - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 148 +++++++++++++++++---------------------- - 1 file changed, 66 insertions(+), 82 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -78,8 +78,10 @@ struct en_rst_data { - - struct en_clk_soc_data { - u32 num_clocks; -+ const struct en_clk_desc *base_clks; - const struct clk_ops pcie_ops; - int (*hw_init)(struct platform_device *pdev, -+ const struct en_clk_soc_data *soc_data, - struct clk_hw_onecell_data *clk_data); - }; - -@@ -450,10 +452,11 @@ static struct clk_hw *en7523_register_pc - .ops = &soc_data->pcie_ops, - }; - struct en_clk_gate *cg; -+ int err; - - cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL); - if (!cg) -- return NULL; -+ return ERR_PTR(-ENOMEM); - - cg->map = clk_map; - cg->hw.init = &init; -@@ -461,12 +464,62 @@ static struct clk_hw *en7523_register_pc - if (init.ops->unprepare) - init.ops->unprepare(&cg->hw); - -- if (clk_hw_register(dev, &cg->hw)) -- return NULL; -+ err = devm_clk_hw_register(dev, &cg->hw); -+ if (err) -+ return ERR_PTR(err); - - return &cg->hw; - } - -+static int en75xx_register_clocks(struct device *dev, -+ const struct en_clk_soc_data *soc_data, -+ struct clk_hw_onecell_data *clk_data, -+ struct regmap *map, struct regmap *clk_map) -+{ -+ struct clk_hw *hw; -+ u32 rate; -+ int i; -+ -+ for (i = 0; i < soc_data->num_clocks - 1; i++) { -+ const struct en_clk_desc *desc = &soc_data->base_clks[i]; -+ u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; -+ int err; -+ -+ err = regmap_read(map, desc->base_reg, &val); -+ if (err) { -+ pr_err("Failed reading fixed clk rate %s: %d\n", -+ desc->name, err); -+ return err; -+ } -+ rate = en7523_get_base_rate(desc, val); -+ -+ err = regmap_read(map, reg, &val); -+ if (err) { -+ pr_err("Failed reading fixed clk div %s: %d\n", -+ desc->name, err); -+ return err; -+ } -+ rate /= en7523_get_div(desc, val); -+ -+ hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); -+ if (IS_ERR(hw)) { -+ pr_err("Failed to register clk %s: %ld\n", -+ desc->name, PTR_ERR(hw)); -+ return PTR_ERR(hw); -+ } -+ -+ clk_data->hws[desc->id] = hw; -+ } -+ -+ hw = en7523_register_pcie_clk(dev, clk_map); -+ if (IS_ERR(hw)) -+ return PTR_ERR(hw); -+ -+ clk_data->hws[EN7523_CLK_PCIE] = hw; -+ -+ return 0; -+} -+ - static int en7581_pci_is_enabled(struct clk_hw *hw) - { - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); -@@ -504,38 +557,6 @@ static void en7581_pci_disable(struct cl - usleep_range(1000, 2000); - } - --static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, -- struct regmap *map, struct regmap *clk_map) --{ -- struct clk_hw *hw; -- u32 rate; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { -- const struct en_clk_desc *desc = &en7523_base_clks[i]; -- u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; -- u32 val; -- -- regmap_read(map, desc->base_reg, &val); -- -- rate = en7523_get_base_rate(desc, val); -- regmap_read(map, reg, &val); -- rate /= en7523_get_div(desc, val); -- -- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); -- if (IS_ERR(hw)) { -- pr_err("Failed to register clk %s: %ld\n", -- desc->name, PTR_ERR(hw)); -- continue; -- } -- -- clk_data->hws[desc->id] = hw; -- } -- -- hw = en7523_register_pcie_clk(dev, clk_map); -- clk_data->hws[EN7523_CLK_PCIE] = hw; --} -- - static const struct regmap_config en7523_clk_regmap_config = { - .reg_bits = 32, - .val_bits = 32, -@@ -543,6 +564,7 @@ static const struct regmap_config en7523 - }; - - static int en7523_clk_hw_init(struct platform_device *pdev, -+ const struct en_clk_soc_data *soc_data, - struct clk_hw_onecell_data *clk_data) - { - void __iomem *base, *np_base; -@@ -566,51 +588,7 @@ static int en7523_clk_hw_init(struct pla - if (IS_ERR(clk_map)) - return PTR_ERR(clk_map); - -- en7523_register_clocks(&pdev->dev, clk_data, map, clk_map); -- -- return 0; --} -- --static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, -- struct regmap *map, struct regmap *clk_map) --{ -- struct clk_hw *hw; -- u32 rate; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) { -- const struct en_clk_desc *desc = &en7581_base_clks[i]; -- u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; -- int err; -- -- err = regmap_read(map, desc->base_reg, &val); -- if (err) { -- pr_err("Failed reading fixed clk rate %s: %d\n", -- desc->name, err); -- continue; -- } -- rate = en7523_get_base_rate(desc, val); -- -- err = regmap_read(map, reg, &val); -- if (err) { -- pr_err("Failed reading fixed clk div %s: %d\n", -- desc->name, err); -- continue; -- } -- rate /= en7523_get_div(desc, val); -- -- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); -- if (IS_ERR(hw)) { -- pr_err("Failed to register clk %s: %ld\n", -- desc->name, PTR_ERR(hw)); -- continue; -- } -- -- clk_data->hws[desc->id] = hw; -- } -- -- hw = en7523_register_pcie_clk(dev, clk_map); -- clk_data->hws[EN7523_CLK_PCIE] = hw; -+ return en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); - } - - static int en7523_reset_update(struct reset_controller_dev *rcdev, -@@ -689,10 +667,12 @@ static int en7581_reset_register(struct - } - - static int en7581_clk_hw_init(struct platform_device *pdev, -+ const struct en_clk_soc_data *soc_data, - struct clk_hw_onecell_data *clk_data) - { - struct regmap *map, *clk_map; - void __iomem *base; -+ int ret; - - map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); - if (IS_ERR(map)) -@@ -706,7 +686,9 @@ static int en7581_clk_hw_init(struct pla - if (IS_ERR(clk_map)) - return PTR_ERR(clk_map); - -- en7581_register_clocks(&pdev->dev, clk_data, map, clk_map); -+ ret = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); -+ if (ret) -+ return ret; - - regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, - REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); -@@ -732,7 +714,7 @@ static int en7523_clk_probe(struct platf - return -ENOMEM; - - clk_data->num = soc_data->num_clocks; -- r = soc_data->hw_init(pdev, clk_data); -+ r = soc_data->hw_init(pdev, soc_data, clk_data); - if (r) - return r; - -@@ -740,6 +722,7 @@ static int en7523_clk_probe(struct platf - } - - static const struct en_clk_soc_data en7523_data = { -+ .base_clks = en7523_base_clks, - .num_clocks = ARRAY_SIZE(en7523_base_clks) + 1, - .pcie_ops = { - .is_enabled = en7523_pci_is_enabled, -@@ -750,6 +733,7 @@ static const struct en_clk_soc_data en75 - }; - - static const struct en_clk_soc_data en7581_data = { -+ .base_clks = en7581_base_clks, - /* We increment num_clocks by 1 to account for additional PCIe clock */ - .num_clocks = ARRAY_SIZE(en7581_base_clks) + 1, - .pcie_ops = { diff --git a/target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch b/target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch deleted file mode 100644 index 31b5bce6369..00000000000 --- a/target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 933030fd268ac111eb9db13b5a90b7c66cd9df41 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 17 Jun 2025 11:38:21 +0200 -Subject: [PATCH 03/10] clk: en7523: convert to full clk_hw implementation - -In preparation for support of .set_rate, convert the clock register -logic from fixed clock implementation to full clk_hw implementation with -dedicated OPs. - -This is just a rework and no behaviour change is expected. - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 83 ++++++++++++++++++++++++++++------------ - 1 file changed, 59 insertions(+), 24 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -69,6 +69,12 @@ struct en_clk_gate { - struct clk_hw hw; - }; - -+struct en_clk { -+ struct regmap *map; -+ const struct en_clk_desc *desc; -+ struct clk_hw hw; -+}; -+ - struct en_rst_data { - const u16 *bank_ofs; - const u16 *idx_map; -@@ -471,44 +477,73 @@ static struct clk_hw *en7523_register_pc - return &cg->hw; - } - -+static unsigned long en75xx_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct en_clk *c = container_of(hw, struct en_clk, hw); -+ const struct en_clk_desc *desc = c->desc; -+ struct regmap *map = c->map; -+ u32 val, reg; -+ u32 rate; -+ int err; -+ -+ err = regmap_read(map, desc->base_reg, &val); -+ if (err) { -+ pr_err("Failed reading fixed clk rate %s: %d\n", -+ desc->name, err); -+ return err; -+ } -+ rate = en7523_get_base_rate(desc, val); -+ -+ reg = desc->div_reg ? desc->div_reg : desc->base_reg; -+ err = regmap_read(map, reg, &val); -+ if (err) { -+ pr_err("Failed reading fixed clk div %s: %d\n", -+ desc->name, err); -+ return err; -+ } -+ -+ return rate / en7523_get_div(desc, val); -+} -+ -+static const struct clk_ops en75xx_clk_ops = { -+ .recalc_rate = en75xx_recalc_rate, -+}; -+ - static int en75xx_register_clocks(struct device *dev, - const struct en_clk_soc_data *soc_data, - struct clk_hw_onecell_data *clk_data, - struct regmap *map, struct regmap *clk_map) - { - struct clk_hw *hw; -- u32 rate; - int i; - - for (i = 0; i < soc_data->num_clocks - 1; i++) { - const struct en_clk_desc *desc = &soc_data->base_clks[i]; -- u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; -+ struct clk_init_data init = { -+ .ops = &en75xx_clk_ops, -+ }; -+ struct en_clk *en_clk; - int err; - -- err = regmap_read(map, desc->base_reg, &val); -- if (err) { -- pr_err("Failed reading fixed clk rate %s: %d\n", -- desc->name, err); -- return err; -- } -- rate = en7523_get_base_rate(desc, val); -+ en_clk = devm_kzalloc(dev, sizeof(*en_clk), GFP_KERNEL); -+ if (!en_clk) -+ return -ENOMEM; - -- err = regmap_read(map, reg, &val); -+ init.name = desc->name; -+ -+ en_clk->map = map; -+ en_clk->desc = desc; -+ en_clk->hw.init = &init; -+ -+ err = devm_clk_hw_register(dev, &en_clk->hw); - if (err) { -- pr_err("Failed reading fixed clk div %s: %d\n", -+ pr_err("Failed to register clk %s: %d\n", - desc->name, err); - return err; - } -- rate /= en7523_get_div(desc, val); -- -- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); -- if (IS_ERR(hw)) { -- pr_err("Failed to register clk %s: %ld\n", -- desc->name, PTR_ERR(hw)); -- return PTR_ERR(hw); -- } - -- clk_data->hws[desc->id] = hw; -+ clk_data->hws[desc->id] = &en_clk->hw; - } - - hw = en7523_register_pcie_clk(dev, clk_map); -@@ -672,7 +707,7 @@ static int en7581_clk_hw_init(struct pla - { - struct regmap *map, *clk_map; - void __iomem *base; -- int ret; -+ int err; - - map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); - if (IS_ERR(map)) -@@ -686,9 +721,9 @@ static int en7581_clk_hw_init(struct pla - if (IS_ERR(clk_map)) - return PTR_ERR(clk_map); - -- ret = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); -- if (ret) -- return ret; -+ err = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); -+ if (err) -+ return err; - - regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, - REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); diff --git a/target/linux/airoha/patches-6.12/600-04-clk-en7523-add-support-for-.set_rate.patch b/target/linux/airoha/patches-6.12/600-04-clk-en7523-add-support-for-.set_rate.patch deleted file mode 100644 index fc2656aeb72..00000000000 --- a/target/linux/airoha/patches-6.12/600-04-clk-en7523-add-support-for-.set_rate.patch +++ /dev/null @@ -1,173 +0,0 @@ -From fe71e8f734a5c9b808a68b8abaa0156de605df4f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 17 Jun 2025 12:28:41 +0200 -Subject: [PATCH 04/10] clk: en7523: add support for .set_rate - -Add support for EN7523 driver to configure rate. The SoC expose both -base clock selector and clock divisor hence it's possible to change the -rate. - -This will be especially needed for new SoC AN7583 that require changes -for the MDIO and the eMMC. - -The clock were assumed correctly configured by the bootloader but this -goes against the rule of "kernel should not depend on external -configuration". - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 141 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 141 insertions(+) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -506,8 +506,149 @@ static unsigned long en75xx_recalc_rate( - return rate / en7523_get_div(desc, val); - } - -+static int en75xx_get_base_val_for_rate(const struct en_clk_desc *desc, -+ int div, unsigned long rate) -+{ -+ int i; -+ -+ /* Single base rate */ -+ if (!desc->base_bits) { -+ if (rate != desc->base_value / div) -+ goto err; -+ -+ return 0; -+ } -+ -+ /* Check every base rate with provided divisor */ -+ for (i = 0; i < desc->n_base_values; i++) -+ if (rate == desc->base_values[i] / div) -+ return i; -+ -+err: -+ return -EINVAL; -+} -+ -+static int en75xx_get_vals_for_rate(const struct en_clk_desc *desc, -+ unsigned long rate, -+ u32 *base_val, u32 *div_val) -+{ -+ int tmp_base_val = 0; -+ int tmp_div_val = 0; -+ -+ if (!desc->base_bits && !desc->div_bits) -+ return -EINVAL; -+ -+ /* Divisor not supported, just search in base rate */ -+ if (!desc->div_bits) { -+ tmp_base_val = en75xx_get_base_val_for_rate(desc, 1, rate); -+ if (tmp_base_val < 0) { -+ pr_err("Invalid rate for clock %s\n", -+ desc->name); -+ return -EINVAL; -+ } -+ -+ goto exit; -+ } -+ -+ /* Check if div0 satisfy the request */ -+ if (desc->div_val0) { -+ tmp_base_val = en75xx_get_base_val_for_rate(desc, -+ desc->div_val0, -+ rate); -+ if (tmp_base_val >= 0) -+ goto exit; -+ -+ /* Skip checking first divisor val */ -+ tmp_div_val = 1; -+ } -+ -+ /* Simulate rate with every divisor supported */ -+ for (; tmp_div_val < BIT(desc->div_bits); tmp_div_val++) { -+ int div = (tmp_div_val + desc->div_offset) * desc->div_step; -+ -+ tmp_base_val = en75xx_get_base_val_for_rate(desc, div, -+ rate); -+ if (tmp_base_val >= 0) -+ goto exit; -+ } -+ -+ if (tmp_div_val == BIT(desc->div_bits)) { -+ pr_err("Invalid rate for clock %s\n", -+ desc->name); -+ return -EINVAL; -+ } -+ -+exit: -+ *base_val = tmp_base_val; -+ *div_val = tmp_div_val; -+ -+ return 0; -+} -+ -+static long en75xx_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct en_clk *en_clk = container_of(hw, struct en_clk, hw); -+ u32 div_val, base_val; -+ int err; -+ -+ /* Just check if the rate is possible */ -+ err = en75xx_get_vals_for_rate(en_clk->desc, rate, -+ &base_val, &div_val); -+ if (err) -+ return err; -+ -+ return rate; -+} -+ -+static int en75xx_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct en_clk *en_clk = container_of(hw, struct en_clk, hw); -+ const struct en_clk_desc *desc = en_clk->desc; -+ struct regmap *map = en_clk->map; -+ u32 base_val, div_val; -+ u32 reg, val, mask; -+ int err; -+ -+ err = en75xx_get_vals_for_rate(en_clk->desc, rate, -+ &base_val, &div_val); -+ if (err) -+ return err; -+ -+ if (desc->div_bits) { -+ reg = desc->div_reg ? desc->div_reg : desc->base_reg; -+ -+ mask = (BIT(desc->div_bits) - 1) << desc->div_shift; -+ val = div_val << desc->div_shift; -+ -+ err = regmap_update_bits(map, reg, mask, val); -+ if (err) { -+ pr_err("Failed to update div reg for clock %s\n", -+ desc->name); -+ return -EINVAL; -+ } -+ } -+ -+ if (desc->base_bits) { -+ mask = (BIT(desc->base_bits) - 1) << desc->base_shift; -+ val = base_val << desc->base_shift; -+ -+ err = regmap_update_bits(map, desc->base_reg, mask, val); -+ if (err) { -+ pr_err("Failed to update reg for clock %s\n", -+ desc->name); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ - static const struct clk_ops en75xx_clk_ops = { - .recalc_rate = en75xx_recalc_rate, -+ .round_rate = en75xx_round_rate, -+ .set_rate = en75xx_set_rate, - }; - - static int en75xx_register_clocks(struct device *dev, diff --git a/target/linux/airoha/patches-6.12/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch b/target/linux/airoha/patches-6.12/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch deleted file mode 100644 index 059d8083cfa..00000000000 --- a/target/linux/airoha/patches-6.12/600-05-clk-en7523-permit-to-reference-Chip-SCU-from-phandle.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 397a132fb8173a9d728bc7c7a31ff5c0590d076f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 17 Jun 2025 12:48:35 +0200 -Subject: [PATCH 05/10] clk: en7523: permit to reference Chip SCU from phandle - -In preparation for support of AN7583 and to make Chip SCU reference more -robust, permit to reference the Chip SCU syscon regmap also with the -"airoha,chip-scu" property in DT. - -Legacy implementation is kept by fallbacking in the absence of -"airoha,chip-scu" property. - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -846,11 +846,16 @@ static int en7581_clk_hw_init(struct pla - const struct en_clk_soc_data *soc_data, - struct clk_hw_onecell_data *clk_data) - { -+ struct device *dev = &pdev->dev; - struct regmap *map, *clk_map; - void __iomem *base; - int err; - -- map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); -+ if (of_property_present(dev->of_node, "airoha,chip-scu")) -+ map = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "airoha,chip-scu"); -+ else -+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); - if (IS_ERR(map)) - return PTR_ERR(map); - diff --git a/target/linux/airoha/patches-6.12/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch b/target/linux/airoha/patches-6.12/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch deleted file mode 100644 index 5de1768f1d0..00000000000 --- a/target/linux/airoha/patches-6.12/600-07-clk-en7523-reword-and-clean-clk_probe-variables.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d05fc5c8a9ab7bbda80e4fc728902f8d48d3e8aa Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 17 Jun 2025 14:53:56 +0200 -Subject: [PATCH 07/10] clk: en7523: reword and clean clk_probe variables - -Rework and clean en7523_clk_probe variables to make them consistent with -the rest of the source. Also apply some minor cleanup for pdev -variables. - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -881,25 +881,27 @@ static int en7581_clk_hw_init(struct pla - - static int en7523_clk_probe(struct platform_device *pdev) - { -- struct device_node *node = pdev->dev.of_node; - const struct en_clk_soc_data *soc_data; - struct clk_hw_onecell_data *clk_data; -- int r; -+ struct device *dev = &pdev->dev; -+ int err; - -- soc_data = device_get_match_data(&pdev->dev); -+ soc_data = device_get_match_data(dev); - -- clk_data = devm_kzalloc(&pdev->dev, -- struct_size(clk_data, hws, soc_data->num_clocks), -+ clk_data = devm_kzalloc(dev, -+ struct_size(clk_data, hws, -+ soc_data->num_clocks), - GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->num = soc_data->num_clocks; -- r = soc_data->hw_init(pdev, soc_data, clk_data); -- if (r) -- return r; -+ err = soc_data->hw_init(pdev, soc_data, clk_data); -+ if (err) -+ return err; - -- return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); -+ return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, -+ clk_data); - } - - static const struct en_clk_soc_data en7523_data = { diff --git a/target/linux/airoha/patches-6.12/600-08-clk-en7523-add-support-for-probing-SCU-child.patch b/target/linux/airoha/patches-6.12/600-08-clk-en7523-add-support-for-probing-SCU-child.patch deleted file mode 100644 index 4d57996a071..00000000000 --- a/target/linux/airoha/patches-6.12/600-08-clk-en7523-add-support-for-probing-SCU-child.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 8f1aea6f4aa61e09eb29b41ff9fffeedd5b2fc0d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 17 Jun 2025 13:15:19 +0200 -Subject: [PATCH 08/10] clk: en7523: add support for probing SCU child - -On new Airoha SoC in the SCU register space additional pheriperal might -be present aside from the clock/reset. The Airoha AN7583 SoC is an -example of this where 2 MDIO controller are present. - -Introduce a bool "probe_child" to trigger probe of child node of the SCU -node. - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -83,6 +84,7 @@ struct en_rst_data { - }; - - struct en_clk_soc_data { -+ bool probe_child; - u32 num_clocks; - const struct en_clk_desc *base_clks; - const struct clk_ops pcie_ops; -@@ -900,8 +902,19 @@ static int en7523_clk_probe(struct platf - if (err) - return err; - -- return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, -- clk_data); -+ err = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, -+ clk_data); -+ if (err) -+ return err; -+ -+ if (soc_data->probe_child) { -+ err = of_platform_populate(dev->of_node, NULL, NULL, -+ dev); -+ if (err) -+ return err; -+ } -+ -+ return 0; - } - - static const struct en_clk_soc_data en7523_data = { diff --git a/target/linux/airoha/patches-6.12/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch b/target/linux/airoha/patches-6.12/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch deleted file mode 100644 index 7c3430bb959..00000000000 --- a/target/linux/airoha/patches-6.12/600-09-dt-bindings-clock-airoha-Document-support-for-AN7583.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 12838dd20851a6eae67061c5f195f31981a4d8c1 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 28 May 2025 02:39:35 +0200 -Subject: [PATCH 09/10] dt-bindings: clock: airoha: Document support for AN7583 - clock - -Document support for Airoha AN7583 clock. This is based on the EN7523 -clock schema with the new requirement of the "airoha,chip-scu" -(previously optional for EN7581). - -Add additional binding for additional clock and reset lines. - -Signed-off-by: Christian Marangi ---- - .../bindings/clock/airoha,en7523-scu.yaml | 9 +++ - include/dt-bindings/clock/en7523-clk.h | 3 + - .../dt-bindings/reset/airoha,an7583-reset.h | 61 +++++++++++++++++++ - 3 files changed, 73 insertions(+) - create mode 100644 include/dt-bindings/reset/airoha,an7583-reset.h - -# diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml -# index bce77a14c938..be9759b86fdc 100644 -# --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml -# +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml -# @@ -32,6 +32,7 @@ properties: -# - enum: -# - airoha,en7523-scu -# - airoha,en7581-scu -# + - airoha,an7583-scu - -# reg: -# items: -# @@ -82,6 +83,14 @@ allOf: -# reg: -# maxItems: 1 - -# + - if: -# + properties: -# + compatible: -# + const: airoha,an7583-scu -# + then: -# + required: -# + - airoha,chip-scu -# + -# additionalProperties: false - -# examples: ---- a/include/dt-bindings/clock/en7523-clk.h -+++ b/include/dt-bindings/clock/en7523-clk.h -@@ -14,4 +14,7 @@ - - #define EN7581_CLK_EMMC 8 - -+#define AN7583_CLK_MDIO0 9 -+#define AN7583_CLK_MDIO1 10 -+ - #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ ---- /dev/null -+++ b/include/dt-bindings/reset/airoha,an7583-reset.h -@@ -0,0 +1,62 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Christian Marangi -+ */ -+ -+#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ -+#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ -+ -+/* RST_CTRL2 */ -+#define AN7583_XPON_PHY_RST 0 -+#define AN7583_GPON_OLT_RST 1 -+#define AN7583_CPU_TIMER2_RST 2 -+#define AN7583_HSUART_RST 3 -+#define AN7583_UART4_RST 4 -+#define AN7583_UART5_RST 5 -+#define AN7583_I2C2_RST 6 -+#define AN7583_XSI_MAC_RST 7 -+#define AN7583_XSI_PHY_RST 8 -+#define AN7583_NPU_RST 9 -+#define AN7583_TRNG_MSTART_RST 10 -+#define AN7583_DUAL_HSI0_RST 11 -+#define AN7583_DUAL_HSI1_RST 12 -+#define AN7583_DUAL_HSI0_MAC_RST 13 -+#define AN7583_DUAL_HSI1_MAC_RST 14 -+#define AN7583_XPON_XFI_RST 15 -+#define AN7583_WDMA_RST 16 -+#define AN7583_WOE0_RST 17 -+#define AN7583_HSDMA_RST 18 -+#define AN7583_TDMA_RST 19 -+#define AN7583_EMMC_RST 20 -+#define AN7583_SOE_RST 21 -+#define AN7583_XFP_MAC_RST 22 -+#define AN7583_MDIO0 23 -+#define AN7583_MDIO1 24 -+/* RST_CTRL1 */ -+#define AN7583_PCM1_ZSI_ISI_RST 25 -+#define AN7583_FE_PDMA_RST 26 -+#define AN7583_FE_QDMA_RST 27 -+#define AN7583_PCM_SPIWP_RST 28 -+#define AN7583_CRYPTO_RST 29 -+#define AN7583_TIMER_RST 30 -+#define AN7583_PCM1_RST 31 -+#define AN7583_UART_RST 32 -+#define AN7583_GPIO_RST 33 -+#define AN7583_GDMA_RST 34 -+#define AN7583_I2C_MASTER_RST 35 -+#define AN7583_PCM2_ZSI_ISI_RST 36 -+#define AN7583_SFC_RST 37 -+#define AN7583_UART2_RST 38 -+#define AN7583_GDMP_RST 39 -+#define AN7583_FE_RST 40 -+#define AN7583_USB_HOST_P0_RST 41 -+#define AN7583_GSW_RST 42 -+#define AN7583_SFC2_PCM_RST 43 -+#define AN7583_PCIE0_RST 44 -+#define AN7583_PCIE1_RST 45 -+#define AN7583_CPU_TIMER_RST 46 -+#define AN7583_PCIE_HB_RST 47 -+#define AN7583_XPON_MAC_RST 48 -+ -+#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_AN7583_H_ */ diff --git a/target/linux/airoha/patches-6.12/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch b/target/linux/airoha/patches-6.12/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch deleted file mode 100644 index 66f5cdb3f8f..00000000000 --- a/target/linux/airoha/patches-6.12/600-10-clk-en7523-add-support-for-Airoha-AN7583-clock.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 3c5cd99f894c23650accf19fef18b5b9bbe83941 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 8 Feb 2025 00:43:27 +0100 -Subject: [PATCH 10/10] clk: en7523: add support for Airoha AN7583 clock - -Add support for Airoha AN7583 clock and reset. - -Airoha AN7583 SoC have the same register address of EN7581 but implement -different bits and additional base clocks. Also reset are different with -the introduction of 2 dedicated MDIO line and drop of some reset lines. - -Signed-off-by: Christian Marangi ---- - drivers/clk/clk-en7523.c | 264 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 264 insertions(+) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #define RST_NR_PER_BANK 32 - -@@ -104,6 +105,14 @@ static const u32 bus7581_base[] = { 6000 - static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; - static const u32 crypto_base[] = { 540000000, 480000000 }; - static const u32 emmc7581_base[] = { 200000000, 150000000 }; -+/* AN7583 */ -+static const u32 gsw7583_base[] = { 540672000, 270336000, 400000000, 200000000 }; -+static const u32 emi7583_base[] = { 540672000, 480000000, 400000000, 300000000 }; -+static const u32 bus7583_base[] = { 600000000, 540672000, 480000000, 400000000 }; -+static const u32 spi7583_base[] = { 400000000, 12500000 }; -+static const u32 npu7583_base[] = { 666000000, 800000000, 720000000, 600000000 }; -+static const u32 crypto7583_base[] = { 540672000, 400000000 }; -+static const u32 emmc7583_base[] = { 150000000, 200000000 }; - - static const struct en_clk_desc en7523_base_clks[] = { - { -@@ -306,6 +315,138 @@ static const struct en_clk_desc en7581_b - } - }; - -+static const struct en_clk_desc an7583_base_clks[] = { -+ { -+ .id = EN7523_CLK_GSW, -+ .name = "gsw", -+ -+ .base_reg = REG_GSW_CLK_DIV_SEL, -+ .base_bits = 2, -+ .base_shift = 8, -+ .base_values = gsw7583_base, -+ .n_base_values = ARRAY_SIZE(gsw7583_base), -+ -+ .div_bits = 3, -+ .div_shift = 0, -+ .div_step = 1, -+ .div_offset = 1, -+ }, { -+ .id = EN7523_CLK_EMI, -+ .name = "emi", -+ -+ .base_reg = REG_EMI_CLK_DIV_SEL, -+ .base_bits = 2, -+ .base_shift = 8, -+ .base_values = emi7583_base, -+ .n_base_values = ARRAY_SIZE(emi7583_base), -+ -+ .div_bits = 3, -+ .div_shift = 0, -+ .div_step = 1, -+ .div_offset = 1, -+ }, { -+ .id = EN7523_CLK_BUS, -+ .name = "bus", -+ -+ .base_reg = REG_BUS_CLK_DIV_SEL, -+ .base_bits = 2, -+ .base_shift = 8, -+ .base_values = bus7583_base, -+ .n_base_values = ARRAY_SIZE(bus7583_base), -+ -+ .div_bits = 3, -+ .div_shift = 0, -+ .div_step = 1, -+ .div_offset = 1, -+ }, { -+ .id = EN7523_CLK_SLIC, -+ .name = "slic", -+ -+ .base_reg = REG_SPI_CLK_FREQ_SEL, -+ .base_bits = 1, -+ .base_shift = 1, -+ .base_values = slic_base, -+ .n_base_values = ARRAY_SIZE(slic_base), -+ -+ .div_reg = REG_SPI_CLK_DIV_SEL, -+ .div_bits = 5, -+ .div_shift = 24, -+ .div_val0 = 20, -+ .div_step = 2, -+ }, { -+ .id = EN7523_CLK_SPI, -+ .name = "spi", -+ -+ .base_reg = REG_SPI_CLK_FREQ_SEL, -+ .base_bits = 1, -+ .base_shift = 0, -+ .base_values = spi7583_base, -+ .n_base_values = ARRAY_SIZE(spi7583_base), -+ -+ .div_reg = REG_SPI_CLK_DIV_SEL, -+ .div_bits = 5, -+ .div_shift = 8, -+ .div_val0 = 40, -+ .div_step = 2, -+ }, { -+ .id = EN7523_CLK_NPU, -+ .name = "npu", -+ -+ .base_reg = REG_NPU_CLK_DIV_SEL, -+ .base_bits = 2, -+ .base_shift = 9, -+ .base_values = npu7583_base, -+ .n_base_values = ARRAY_SIZE(npu7583_base), -+ -+ .div_bits = 3, -+ .div_shift = 0, -+ .div_step = 1, -+ .div_offset = 1, -+ }, { -+ .id = EN7523_CLK_CRYPTO, -+ .name = "crypto", -+ -+ .base_reg = REG_CRYPTO_CLKSRC2, -+ .base_bits = 1, -+ .base_shift = 0, -+ .base_values = crypto7583_base, -+ .n_base_values = ARRAY_SIZE(crypto7583_base), -+ }, { -+ .id = EN7581_CLK_EMMC, -+ .name = "emmc", -+ -+ .base_reg = REG_CRYPTO_CLKSRC2, -+ .base_bits = 1, -+ .base_shift = 13, -+ .base_values = emmc7583_base, -+ .n_base_values = ARRAY_SIZE(emmc7583_base), -+ }, { -+ .id = AN7583_CLK_MDIO0, -+ .name = "mdio0", -+ -+ .base_reg = REG_CRYPTO_CLKSRC2, -+ -+ .base_value = 25000000, -+ -+ .div_bits = 4, -+ .div_shift = 15, -+ .div_step = 1, -+ .div_offset = 1, -+ }, { -+ .id = AN7583_CLK_MDIO1, -+ .name = "mdio1", -+ -+ .base_reg = REG_CRYPTO_CLKSRC2, -+ -+ .base_value = 25000000, -+ -+ .div_bits = 4, -+ .div_shift = 19, -+ .div_step = 1, -+ .div_offset = 1, -+ } -+}; -+ - static const u16 en7581_rst_ofs[] = { - REG_RST_CTRL2, - REG_RST_CTRL1, -@@ -369,6 +510,60 @@ static const u16 en7581_rst_map[] = { - [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, - }; - -+static const u16 an7583_rst_map[] = { -+ /* RST_CTRL2 */ -+ [AN7583_XPON_PHY_RST] = 0, -+ [AN7583_GPON_OLT_RST] = 1, -+ [AN7583_CPU_TIMER2_RST] = 2, -+ [AN7583_HSUART_RST] = 3, -+ [AN7583_UART4_RST] = 4, -+ [AN7583_UART5_RST] = 5, -+ [AN7583_I2C2_RST] = 6, -+ [AN7583_XSI_MAC_RST] = 7, -+ [AN7583_XSI_PHY_RST] = 8, -+ [AN7583_NPU_RST] = 9, -+ [AN7583_TRNG_MSTART_RST] = 12, -+ [AN7583_DUAL_HSI0_RST] = 13, -+ [AN7583_DUAL_HSI1_RST] = 14, -+ [AN7583_DUAL_HSI0_MAC_RST] = 16, -+ [AN7583_DUAL_HSI1_MAC_RST] = 17, -+ [AN7583_XPON_XFI_RST] = 18, -+ [AN7583_WDMA_RST] = 19, -+ [AN7583_WOE0_RST] = 20, -+ [AN7583_HSDMA_RST] = 22, -+ [AN7583_TDMA_RST] = 24, -+ [AN7583_EMMC_RST] = 25, -+ [AN7583_SOE_RST] = 26, -+ [AN7583_XFP_MAC_RST] = 28, -+ [AN7583_MDIO0] = 30, -+ [AN7583_MDIO1] = 31, -+ /* RST_CTRL1 */ -+ [AN7583_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, -+ [AN7583_FE_PDMA_RST] = RST_NR_PER_BANK + 1, -+ [AN7583_FE_QDMA_RST] = RST_NR_PER_BANK + 2, -+ [AN7583_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4, -+ [AN7583_CRYPTO_RST] = RST_NR_PER_BANK + 6, -+ [AN7583_TIMER_RST] = RST_NR_PER_BANK + 8, -+ [AN7583_PCM1_RST] = RST_NR_PER_BANK + 11, -+ [AN7583_UART_RST] = RST_NR_PER_BANK + 12, -+ [AN7583_GPIO_RST] = RST_NR_PER_BANK + 13, -+ [AN7583_GDMA_RST] = RST_NR_PER_BANK + 14, -+ [AN7583_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, -+ [AN7583_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, -+ [AN7583_SFC_RST] = RST_NR_PER_BANK + 18, -+ [AN7583_UART2_RST] = RST_NR_PER_BANK + 19, -+ [AN7583_GDMP_RST] = RST_NR_PER_BANK + 20, -+ [AN7583_FE_RST] = RST_NR_PER_BANK + 21, -+ [AN7583_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, -+ [AN7583_GSW_RST] = RST_NR_PER_BANK + 23, -+ [AN7583_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, -+ [AN7583_PCIE0_RST] = RST_NR_PER_BANK + 26, -+ [AN7583_PCIE1_RST] = RST_NR_PER_BANK + 27, -+ [AN7583_CPU_TIMER_RST] = RST_NR_PER_BANK + 28, -+ [AN7583_PCIE_HB_RST] = RST_NR_PER_BANK + 29, -+ [AN7583_XPON_MAC_RST] = RST_NR_PER_BANK + 31, -+}; -+ - static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) - { - if (!desc->base_bits) -@@ -881,6 +1076,62 @@ static int en7581_clk_hw_init(struct pla - return en7581_reset_register(&pdev->dev, clk_map); - } - -+static int an7583_reset_register(struct device *dev, struct regmap *map) -+{ -+ struct en_rst_data *rst_data; -+ -+ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); -+ if (!rst_data) -+ return -ENOMEM; -+ -+ rst_data->bank_ofs = en7581_rst_ofs; -+ rst_data->idx_map = an7583_rst_map; -+ rst_data->map = map; -+ -+ rst_data->rcdev.nr_resets = ARRAY_SIZE(an7583_rst_map); -+ rst_data->rcdev.of_xlate = en7523_reset_xlate; -+ rst_data->rcdev.ops = &en7581_reset_ops; -+ rst_data->rcdev.of_node = dev->of_node; -+ rst_data->rcdev.of_reset_n_cells = 1; -+ rst_data->rcdev.owner = THIS_MODULE; -+ rst_data->rcdev.dev = dev; -+ -+ return devm_reset_controller_register(dev, &rst_data->rcdev); -+} -+ -+static int an7583_clk_hw_init(struct platform_device *pdev, -+ const struct en_clk_soc_data *soc_data, -+ struct clk_hw_onecell_data *clk_data) -+{ -+ struct device *dev = &pdev->dev; -+ struct regmap *map, *clk_map; -+ void __iomem *base; -+ int err; -+ -+ map = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,chip-scu"); -+ if (IS_ERR(map)) -+ return PTR_ERR(map); -+ -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config); -+ if (IS_ERR(clk_map)) -+ return PTR_ERR(clk_map); -+ -+ err = en75xx_register_clocks(dev, soc_data, clk_data, map, clk_map); -+ if (err) -+ return err; -+ -+ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR, -+ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); -+ regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, -+ FIELD_PREP(REG_PCIE_CTRL, 3)); -+ -+ return an7583_reset_register(dev, clk_map); -+} -+ - static int en7523_clk_probe(struct platform_device *pdev) - { - const struct en_clk_soc_data *soc_data; -@@ -940,9 +1191,23 @@ static const struct en_clk_soc_data en75 - .hw_init = en7581_clk_hw_init, - }; - -+static const struct en_clk_soc_data an7583_data = { -+ .probe_child = true, -+ .base_clks = an7583_base_clks, -+ /* We increment num_clocks by 1 to account for additional PCIe clock */ -+ .num_clocks = ARRAY_SIZE(an7583_base_clks) + 1, -+ .pcie_ops = { -+ .is_enabled = en7581_pci_is_enabled, -+ .enable = en7581_pci_enable, -+ .disable = en7581_pci_disable, -+ }, -+ .hw_init = an7583_clk_hw_init, -+}; -+ - static const struct of_device_id of_match_clk_en7523[] = { - { .compatible = "airoha,en7523-scu", .data = &en7523_data }, - { .compatible = "airoha,en7581-scu", .data = &en7581_data }, -+ { .compatible = "airoha,an7583-scu", .data = &an7583_data }, - { /* sentinel */ } - }; - diff --git a/target/linux/airoha/patches-6.12/600-11-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch b/target/linux/airoha/patches-6.12/600-11-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch deleted file mode 100644 index 0c391ebce99..00000000000 --- a/target/linux/airoha/patches-6.12/600-11-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 38195ddfcea372924a68b64f7a6f9235488160be Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sat, 20 Sep 2025 03:57:25 +0300 -Subject: [PATCH 1/3] dt-bindings: clock: airoha: Add reset support to EN7523 - clock binding - -Introduce reset capability to EN7523 device-tree clock binding -documentation. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: Rob Herring (Arm) ---- - .../bindings/clock/airoha,en7523-scu.yaml | 3 +- - .../dt-bindings/reset/airoha,en7523-reset.h | 61 +++++++++++++++++++ - 2 files changed, 62 insertions(+), 2 deletions(-) - create mode 100644 include/dt-bindings/reset/airoha,en7523-reset.h - ---- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml -+++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml -@@ -64,8 +64,6 @@ allOf: - - description: scu base address - - description: misc scu base address - -- '#reset-cells': false -- - - if: - properties: - compatible: -@@ -89,6 +87,7 @@ examples: - reg = <0x1fa20000 0x400>, - <0x1fb00000 0x1000>; - #clock-cells = <1>; -+ #reset-cells = <1>; - }; - - - | ---- /dev/null -+++ b/include/dt-bindings/reset/airoha,en7523-reset.h -@@ -0,0 +1,61 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (C) 2024 iopsys Software Solutions AB. -+ * Copyright (C) 2025 Genexis AB. -+ * -+ * Author: Mikhail Kshevetskiy -+ * -+ * based on -+ * include/dt-bindings/reset/airoha,en7581-reset.h -+ * by Lorenzo Bianconi -+ */ -+ -+#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ -+#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ -+ -+/* RST_CTRL2 */ -+#define EN7523_XPON_PHY_RST 0 -+#define EN7523_XSI_MAC_RST 1 -+#define EN7523_XSI_PHY_RST 2 -+#define EN7523_NPU_RST 3 -+#define EN7523_I2S_RST 4 -+#define EN7523_TRNG_RST 5 -+#define EN7523_TRNG_MSTART_RST 6 -+#define EN7523_DUAL_HSI0_RST 7 -+#define EN7523_DUAL_HSI1_RST 8 -+#define EN7523_HSI_RST 9 -+#define EN7523_DUAL_HSI0_MAC_RST 10 -+#define EN7523_DUAL_HSI1_MAC_RST 11 -+#define EN7523_HSI_MAC_RST 12 -+#define EN7523_WDMA_RST 13 -+#define EN7523_WOE0_RST 14 -+#define EN7523_WOE1_RST 15 -+#define EN7523_HSDMA_RST 16 -+#define EN7523_I2C2RBUS_RST 17 -+#define EN7523_TDMA_RST 18 -+/* RST_CTRL1 */ -+#define EN7523_PCM1_ZSI_ISI_RST 19 -+#define EN7523_FE_PDMA_RST 20 -+#define EN7523_FE_QDMA_RST 21 -+#define EN7523_PCM_SPIWP_RST 22 -+#define EN7523_CRYPTO_RST 23 -+#define EN7523_TIMER_RST 24 -+#define EN7523_PCM1_RST 25 -+#define EN7523_UART_RST 26 -+#define EN7523_GPIO_RST 27 -+#define EN7523_GDMA_RST 28 -+#define EN7523_I2C_MASTER_RST 29 -+#define EN7523_PCM2_ZSI_ISI_RST 30 -+#define EN7523_SFC_RST 31 -+#define EN7523_UART2_RST 32 -+#define EN7523_GDMP_RST 33 -+#define EN7523_FE_RST 34 -+#define EN7523_USB_HOST_P0_RST 35 -+#define EN7523_GSW_RST 36 -+#define EN7523_SFC2_PCM_RST 37 -+#define EN7523_PCIE0_RST 38 -+#define EN7523_PCIE1_RST 39 -+#define EN7523_PCIE_HB_RST 40 -+#define EN7523_XPON_MAC_RST 41 -+ -+#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ */ diff --git a/target/linux/airoha/patches-6.12/600-12-clk-en7523-Add-reset-controller-support-for-EN7523-S.patch b/target/linux/airoha/patches-6.12/600-12-clk-en7523-Add-reset-controller-support-for-EN7523-S.patch deleted file mode 100644 index c658e2f7757..00000000000 --- a/target/linux/airoha/patches-6.12/600-12-clk-en7523-Add-reset-controller-support-for-EN7523-S.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 37de26f9d2f55cd74af55cb29c2860b5989bb728 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sat, 20 Sep 2025 03:57:25 +0300 -Subject: [PATCH 2/3] clk: en7523: Add reset-controller support for EN7523 SoC - -Introduce reset API support to EN7523 clock driver. EN7523 uses the -same reset logic as EN7581, so just reuse existing code. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno ---- - drivers/clk/clk-en7523.c | 96 ++++++++++++++++++++++++++++------------ - 1 file changed, 67 insertions(+), 29 deletions(-) - ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -452,6 +453,53 @@ static const u16 en7581_rst_ofs[] = { - REG_RST_CTRL1, - }; - -+static const u16 en7523_rst_map[] = { -+ /* RST_CTRL2 */ -+ [EN7523_XPON_PHY_RST] = 0, -+ [EN7523_XSI_MAC_RST] = 7, -+ [EN7523_XSI_PHY_RST] = 8, -+ [EN7523_NPU_RST] = 9, -+ [EN7523_I2S_RST] = 10, -+ [EN7523_TRNG_RST] = 11, -+ [EN7523_TRNG_MSTART_RST] = 12, -+ [EN7523_DUAL_HSI0_RST] = 13, -+ [EN7523_DUAL_HSI1_RST] = 14, -+ [EN7523_HSI_RST] = 15, -+ [EN7523_DUAL_HSI0_MAC_RST] = 16, -+ [EN7523_DUAL_HSI1_MAC_RST] = 17, -+ [EN7523_HSI_MAC_RST] = 18, -+ [EN7523_WDMA_RST] = 19, -+ [EN7523_WOE0_RST] = 20, -+ [EN7523_WOE1_RST] = 21, -+ [EN7523_HSDMA_RST] = 22, -+ [EN7523_I2C2RBUS_RST] = 23, -+ [EN7523_TDMA_RST] = 24, -+ /* RST_CTRL1 */ -+ [EN7523_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, -+ [EN7523_FE_PDMA_RST] = RST_NR_PER_BANK + 1, -+ [EN7523_FE_QDMA_RST] = RST_NR_PER_BANK + 2, -+ [EN7523_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4, -+ [EN7523_CRYPTO_RST] = RST_NR_PER_BANK + 6, -+ [EN7523_TIMER_RST] = RST_NR_PER_BANK + 8, -+ [EN7523_PCM1_RST] = RST_NR_PER_BANK + 11, -+ [EN7523_UART_RST] = RST_NR_PER_BANK + 12, -+ [EN7523_GPIO_RST] = RST_NR_PER_BANK + 13, -+ [EN7523_GDMA_RST] = RST_NR_PER_BANK + 14, -+ [EN7523_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, -+ [EN7523_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, -+ [EN7523_SFC_RST] = RST_NR_PER_BANK + 18, -+ [EN7523_UART2_RST] = RST_NR_PER_BANK + 19, -+ [EN7523_GDMP_RST] = RST_NR_PER_BANK + 20, -+ [EN7523_FE_RST] = RST_NR_PER_BANK + 21, -+ [EN7523_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, -+ [EN7523_GSW_RST] = RST_NR_PER_BANK + 23, -+ [EN7523_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, -+ [EN7523_PCIE0_RST] = RST_NR_PER_BANK + 26, -+ [EN7523_PCIE1_RST] = RST_NR_PER_BANK + 27, -+ [EN7523_PCIE_HB_RST] = RST_NR_PER_BANK + 29, -+ [EN7523_XPON_MAC_RST] = RST_NR_PER_BANK + 31, -+}; -+ - static const u16 en7581_rst_map[] = { - /* RST_CTRL2 */ - [EN7581_XPON_PHY_RST] = 0, -@@ -564,6 +612,9 @@ static const u16 an7583_rst_map[] = { - [AN7583_XPON_MAC_RST] = RST_NR_PER_BANK + 31, - }; - -+static int en7581_reset_register(struct device *dev, struct regmap *map, -+ const u16 *rst_map, int nr_resets); -+ - static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) - { - if (!desc->base_bits) -@@ -942,6 +993,7 @@ static int en7523_clk_hw_init(struct pla - { - void __iomem *base, *np_base; - struct regmap *map, *clk_map; -+ int err; - - base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(base)) -@@ -961,7 +1013,13 @@ static int en7523_clk_hw_init(struct pla - if (IS_ERR(clk_map)) - return PTR_ERR(clk_map); - -- return en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); -+ -+ err = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map); -+ if (err) -+ return err; -+ -+ return en7581_reset_register(&pdev->dev, clk_map, en7523_rst_map, -+ ARRAY_SIZE(en7523_rst_map)); - } - - static int en7523_reset_update(struct reset_controller_dev *rcdev, -@@ -1016,7 +1074,8 @@ static const struct reset_control_ops en - .status = en7523_reset_status, - }; - --static int en7581_reset_register(struct device *dev, struct regmap *map) -+static int en7581_reset_register(struct device *dev, struct regmap *map, -+ const u16 *rst_map, int nr_resets) - { - struct en_rst_data *rst_data; - -@@ -1025,10 +1084,10 @@ static int en7581_reset_register(struct - return -ENOMEM; - - rst_data->bank_ofs = en7581_rst_ofs; -- rst_data->idx_map = en7581_rst_map; -+ rst_data->idx_map = rst_map; - rst_data->map = map; - -- rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); -+ rst_data->rcdev.nr_resets = nr_resets; - rst_data->rcdev.of_xlate = en7523_reset_xlate; - rst_data->rcdev.ops = &en7581_reset_ops; - rst_data->rcdev.of_node = dev->of_node; -@@ -1073,30 +1132,8 @@ static int en7581_clk_hw_init(struct pla - regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, - FIELD_PREP(REG_PCIE_CTRL, 3)); - -- return en7581_reset_register(&pdev->dev, clk_map); --} -- --static int an7583_reset_register(struct device *dev, struct regmap *map) --{ -- struct en_rst_data *rst_data; -- -- rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); -- if (!rst_data) -- return -ENOMEM; -- -- rst_data->bank_ofs = en7581_rst_ofs; -- rst_data->idx_map = an7583_rst_map; -- rst_data->map = map; -- -- rst_data->rcdev.nr_resets = ARRAY_SIZE(an7583_rst_map); -- rst_data->rcdev.of_xlate = en7523_reset_xlate; -- rst_data->rcdev.ops = &en7581_reset_ops; -- rst_data->rcdev.of_node = dev->of_node; -- rst_data->rcdev.of_reset_n_cells = 1; -- rst_data->rcdev.owner = THIS_MODULE; -- rst_data->rcdev.dev = dev; -- -- return devm_reset_controller_register(dev, &rst_data->rcdev); -+ return en7581_reset_register(&pdev->dev, clk_map, en7581_rst_map, -+ ARRAY_SIZE(en7581_rst_map)); - } - - static int an7583_clk_hw_init(struct platform_device *pdev, -@@ -1129,7 +1166,8 @@ static int an7583_clk_hw_init(struct pla - regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL, - FIELD_PREP(REG_PCIE_CTRL, 3)); - -- return an7583_reset_register(dev, clk_map); -+ return en7581_reset_register(dev, clk_map, an7583_rst_map, -+ ARRAY_SIZE(an7583_rst_map)); - } - - static int en7523_clk_probe(struct platform_device *pdev) diff --git a/target/linux/airoha/patches-6.12/600-13-ARM-dts-airoha-update-EN7523-dtsi-to-support-resets.patch b/target/linux/airoha/patches-6.12/600-13-ARM-dts-airoha-update-EN7523-dtsi-to-support-resets.patch deleted file mode 100644 index 3ed155aaf0a..00000000000 --- a/target/linux/airoha/patches-6.12/600-13-ARM-dts-airoha-update-EN7523-dtsi-to-support-resets.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 6e5e3a8e20d12f60a1b902160b92337b392b1c18 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Sat, 20 Sep 2025 03:57:25 +0300 -Subject: [PATCH 3/3] ARM: dts: airoha: update EN7523 dtsi to support resets - -This patch updates EN7523 dtsi to reflect the reset-controller -support for EN7523 SoC. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: AngeloGioacchino Del Regno ---- - arch/arm/boot/dts/airoha/en7523.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm/boot/dts/airoha/en7523.dtsi -+++ b/arch/arm/boot/dts/airoha/en7523.dtsi -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - / { - interrupt-parent = <&gic>; -@@ -91,6 +92,7 @@ - reg = <0x1fa20000 0x400>, - <0x1fb00000 0x1000>; - #clock-cells = <1>; -+ #reset-cells = <1>; - }; - - gic: interrupt-controller@9000000 { diff --git a/target/linux/airoha/patches-6.12/604-01-net-pcs-airoha-add-support-for-AN7583.patch b/target/linux/airoha/patches-6.12/604-01-net-pcs-airoha-add-support-for-AN7583.patch deleted file mode 100644 index 0801c2bec17..00000000000 --- a/target/linux/airoha/patches-6.12/604-01-net-pcs-airoha-add-support-for-AN7583.patch +++ /dev/null @@ -1,3386 +0,0 @@ -From e4c0769d72f34035f4ac415ad155bbdf5a8a4f90 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 25 Jun 2025 00:00:59 +0200 -Subject: [PATCH 18/20] net: pcs: airoha: add support for Airoha AN7583 SoC - -Add support for Airoha AN7583 PCS. This use a new analog PHY -implementation that doesn't require manual calibration but makes use of -internal algo to lock to the center of the band EYE. - -Signed-off-by: Christian Marangi ---- - drivers/net/pcs/airoha/Kconfig | 7 + - drivers/net/pcs/airoha/Makefile | 3 + - drivers/net/pcs/airoha/pcs-airoha-common.c | 169 +- - drivers/net/pcs/airoha/pcs-airoha.h | 452 ++++ - drivers/net/pcs/airoha/pcs-an7583.c | 2349 ++++++++++++++++++++ - 5 files changed, 2970 insertions(+), 10 deletions(-) - create mode 100644 drivers/net/pcs/airoha/pcs-an7583.c - ---- a/drivers/net/pcs/airoha/Kconfig -+++ b/drivers/net/pcs/airoha/Kconfig -@@ -10,3 +10,10 @@ config PCS_AIROHA_AN7581 - help - This module provides helper to phylink for managing the Airoha - AN7581 PCS for SoC Ethernet and PON SERDES. -+ -+config PCS_AIROHA_AN7583 -+ tristate "Airoha AN7583 PCS driver" -+ select PCS_AIROHA -+ help -+ This module provides helper to phylink for managing the Airoha -+ AN7583 PCS for SoC Ethernet and PON SERDES. ---- a/drivers/net/pcs/airoha/Makefile -+++ b/drivers/net/pcs/airoha/Makefile -@@ -5,3 +5,6 @@ pcs-airoha-objs := pcs-airoha-common.o - ifdef CONFIG_PCS_AIROHA_AN7581 - pcs-airoha-objs += pcs-an7581.o - endif -+ifdef CONFIG_PCS_AIROHA_AN7583 -+pcs-airoha-objs += pcs-an7583.o -+endif ---- a/drivers/net/pcs/airoha/pcs-airoha-common.c -+++ b/drivers/net/pcs/airoha/pcs-airoha-common.c -@@ -21,6 +21,7 @@ - static void airoha_pcs_setup_scu_eth(struct airoha_pcs_priv *priv, - phy_interface_t interface) - { -+ struct device *dev = priv->dev; - u32 xsi_sel; - - switch (interface) { -@@ -38,6 +39,12 @@ static void airoha_pcs_setup_scu_eth(str - regmap_update_bits(priv->scu, AIROHA_SCU_SSR3, - AIROHA_SCU_ETH_XSI_SEL, - xsi_sel); -+ -+ /* AN7583 require additional setting */ -+ if (device_is_compatible(dev, "airoha,an7583-pcs-eth")) -+ regmap_update_bits(priv->scu, AIROHA_SCU_WAN_CONF, -+ AIROHA_SCU_ETH_MAC_SEL, -+ AIROHA_SCU_ETH_MAC_SEL_XFI); - } - - static void airoha_pcs_setup_scu_pon(struct airoha_pcs_priv *priv, -@@ -71,7 +78,7 @@ static void airoha_pcs_setup_scu_pon(str - wan_sel); - } - --static void airoha_pcs_setup_scu_pcie(struct airoha_pcs_priv *priv, -+static void an7581_pcs_setup_scu_pcie(struct airoha_pcs_priv *priv, - int index, phy_interface_t interface) - { - u32 xsi_sel; -@@ -111,6 +118,26 @@ static void airoha_pcs_setup_scu_pcie(st - } - } - -+static void an7583_pcs_setup_scu_pcie(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ u32 xsi_sel; -+ -+ if (priv->phy) -+ return; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ default: -+ xsi_sel = AIROHA_SCU_PCIE_XSI1_USXGMII; -+ } -+ -+ regmap_update_bits(priv->scu, AIROHA_SCU_SSTR, -+ AIROHA_SCU_PCIE_XSI1_SEL, -+ xsi_sel); -+} -+ - static int airoha_pcs_setup_scu(struct airoha_pcs_priv *priv, - int index, phy_interface_t interface) - { -@@ -125,7 +152,10 @@ static int airoha_pcs_setup_scu(struct a - airoha_pcs_setup_scu_pon(priv, interface); - break; - case AIROHA_PCS_PCIE: -- airoha_pcs_setup_scu_pcie(priv, index, interface); -+ if (device_is_compatible(priv->dev, "airoha,an7581-pcs-pcie")) -+ an7581_pcs_setup_scu_pcie(priv, index, interface); -+ else -+ an7583_pcs_setup_scu_pcie(priv, index, interface); - break; - case AIROHA_PCS_USB: - break; -@@ -147,18 +177,25 @@ static int airoha_pcs_setup_scu(struct a - - static void airoha_pcs_init_usxgmii(struct airoha_pcs_priv *priv, int index) - { -+ const struct airoha_pcs_match_data *data = priv->data; - struct airoha_pcs_maps *maps = &priv->maps[index]; - - regmap_set_bits(maps->multi_sgmii, AIROHA_PCS_MULTI_SGMII_MSG_RX_CTRL_0, - AIROHA_PCS_HSGMII_XFI_SEL); - - /* Disable Hibernation */ -- regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1, -- AIROHA_PCS_USXGMII_SPEED_SEL_H); -+ if (data->hibernation_workaround) -+ regmap_clear_bits(maps->usxgmii_pcs, AIROHA_PCS_USXGMII_PCS_CTROL_1, -+ AIROHA_PCS_USXGMII_SPEED_SEL_H); - - /* FIXME: wait Airoha */ - /* Avoid PCS sending garbage to MAC in some HW revision (E0) */ -- regmap_write(maps->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); -+ if (data->usxgmii_ber_time_fixup) -+ regmap_write(maps->usxgmii_pcs, AIROHA_PCS_USGMII_VENDOR_DEFINE_116, 0); -+ -+ if (data->usxgmii_rx_gb_out_vld_tweak) -+ regmap_clear_bits(maps->usxgmii_pcs, AN7583_PCS_USXGMII_RTL_MODIFIED, -+ AIROHA_PCS_USXGMII_MODIFIED_RX_GB_OUT_VLD); - } - - static void airoha_pcs_init_hsgmii(struct airoha_pcs_priv *priv, int index) -@@ -512,6 +549,13 @@ static int airoha_pcs_config(struct phyl - AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, - AIROHA_PCS_USXGMII_RATE_UPDATE_MODE); - } -+ -+ if (data->usxgmii_xfi_mode_sel && -+ neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) -+ regmap_set_bits(maps->usxgmii_pcs, -+ AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7, -+ AIROHA_PCS_USXGMII_XFI_MODE_TX_SEL | -+ AIROHA_PCS_USXGMII_XFI_MODE_RX_SEL); - } - - /* Clear any force bit that my be set by bootloader */ -@@ -1015,10 +1059,14 @@ static int airoha_pcs_usb_alloc_maps(str - if (ret) - return ret; - -+ /* For AN7583 PCS ANA is controlled by PHY driver */ -+ if (device_is_compatible(&pdev->dev, "airoha,an7583-pcs-usb")) -+ return 0; -+ - return airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); - } - --static int airoha_pcs_pcie_alloc_maps(struct platform_device *pdev, -+static int an7581_pcs_pcie_alloc_maps(struct platform_device *pdev, - struct airoha_pcs_priv *priv) - { - struct airoha_pcs_maps *maps = priv->maps; -@@ -1115,6 +1163,60 @@ static struct phylink_pcs *airoha_pcs_ge - return &priv->ports[index].pcs; - } - -+static int an7583_pcs_pcie_alloc_maps(struct platform_device *pdev, -+ struct airoha_pcs_priv *priv) -+{ -+ struct airoha_pcs_maps *maps = priv->maps; -+ int ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_mac", &maps[0].pcs_mac); -+ if (ret) -+ return ret; -+ -+ /* On AN7583 PCS MAC is shared by SGMII/HSGMII is provided by PCIe1 PHY -+ * and USXGMII is provided by PCIE0 ANA and PMA. -+ */ -+ if (priv->phy) { -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_an0", &maps[0].hsgmii_an); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_pcs0", &maps[0].hsgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp0", &maps[0].hsgmii_rate_adp); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii0", &maps[0].multi_sgmii); -+ if (ret) -+ return ret; -+ } else { -+ ret = airoha_pcs_init_named_regmap(pdev, "hsgmii_rate_adp1", &maps[0].hsgmii_rate_adp); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "multi_sgmii1", &maps[0].multi_sgmii); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "usxgmii1", &maps[0].usxgmii_pcs); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_pma", &priv->pcs_pma[0]); -+ if (ret) -+ return ret; -+ -+ ret = airoha_pcs_init_named_regmap(pdev, "pcs_ana", &priv->pcs_ana); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int airoha_pcs_probe(struct platform_device *pdev) - { - const struct airoha_pcs_match_data *data; -@@ -1136,14 +1238,19 @@ static int airoha_pcs_probe(struct platf - priv->dev = dev; - priv->data = data; - -- if (data->port_type == AIROHA_PCS_USB) { -+ if (data->port_type == AIROHA_PCS_USB || -+ device_is_compatible(dev, "airoha,an7583-pcs-pcie")) { - struct phy *phy; - -+ /* For AN7583 PCIe PCS PHY is optional */ - phy = devm_phy_get(dev, NULL); -- if (IS_ERR(phy)) -+ if (IS_ERR(phy) && -+ (data->port_type == AIROHA_PCS_USB || -+ PTR_ERR(phy) != -ENODEV)) - return dev_err_probe(dev, PTR_ERR(phy), "failed to get phy\n"); - -- priv->phy = phy; -+ if (!IS_ERR(phy)) -+ priv->phy = phy; - } - - switch (data->port_type) { -@@ -1155,7 +1262,10 @@ static int airoha_pcs_probe(struct platf - - break; - case AIROHA_PCS_PCIE: -- ret = airoha_pcs_pcie_alloc_maps(pdev, priv); -+ if (device_is_compatible(dev, "airoha,an7581-pcs-pcie")) -+ ret = an7581_pcs_pcie_alloc_maps(pdev, priv); -+ else -+ ret = an7583_pcs_pcie_alloc_maps(pdev, priv); - if (ret) - return ret; - -@@ -1260,6 +1370,8 @@ static void airoha_pcs_remove(struct pla - static const struct airoha_pcs_match_data an7581_pcs_eth = { - .num_port = 1, - .port_type = AIROHA_PCS_ETH, -+ .hibernation_workaround = true, -+ .usxgmii_ber_time_fixup = true, - .alloc_regmap_fields = an7581_pcs_alloc_regmap_fields, - .bringup = an7581_pcs_bringup, - .link_up = an7581_pcs_phya_link_up, -@@ -1269,6 +1381,8 @@ static const struct airoha_pcs_match_dat - static const struct airoha_pcs_match_data an7581_pcs_pon = { - .num_port = 1, - .port_type = AIROHA_PCS_PON, -+ .hibernation_workaround = true, -+ .usxgmii_ber_time_fixup = true, - .alloc_regmap_fields = an7581_pcs_alloc_regmap_fields, - .bringup = an7581_pcs_bringup, - .link_up = an7581_pcs_phya_link_up, -@@ -1277,6 +1391,8 @@ static const struct airoha_pcs_match_dat - static const struct airoha_pcs_match_data an7581_pcs_pcie = { - .num_port = 2, - .port_type = AIROHA_PCS_PCIE, -+ .hibernation_workaround = true, -+ .usxgmii_ber_time_fixup = true, - .alloc_regmap_fields = an7581_pcs_pcie_alloc_regmap_fields, - .bringup = an7581_pcs_bringup, - .link_up = an7581_pcs_phya_link_up, -@@ -1288,11 +1404,44 @@ static const struct airoha_pcs_match_dat - .bringup = an7581_pcs_usb_bringup, - }; - -+static const struct airoha_pcs_match_data an7583_pcs_eth = { -+ .port_type = AIROHA_PCS_ETH, -+ .usxgmii_rx_gb_out_vld_tweak = true, -+ .usxgmii_xfi_mode_sel = true, -+ .bringup = an7583_pcs_common_phya_bringup, -+ .link_up = an7583_pcs_common_phya_link_up, -+}; -+ -+static const struct airoha_pcs_match_data an7583_pcs_pon = { -+ .port_type = AIROHA_PCS_PON, -+ .usxgmii_rx_gb_out_vld_tweak = true, -+ .usxgmii_xfi_mode_sel = true, -+ .bringup = an7583_pcs_common_phya_bringup, -+ .link_up = an7583_pcs_common_phya_link_up, -+}; -+ -+static const struct airoha_pcs_match_data an7583_pcs_pcie = { -+ .port_type = AIROHA_PCS_PCIE, -+ .usxgmii_rx_gb_out_vld_tweak = true, -+ .usxgmii_xfi_mode_sel = true, -+ .bringup = an7583_pcs_common_phya_bringup, -+ .link_up = an7583_pcs_common_phya_link_up, -+}; -+ -+static const struct airoha_pcs_match_data an7583_pcs_usb = { -+ .port_type = AIROHA_PCS_USB, -+ .bringup = an7583_pcs_usb_phya_bringup, -+}; -+ - static const struct of_device_id airoha_pcs_of_table[] = { - { .compatible = "airoha,an7581-pcs-eth", .data = &an7581_pcs_eth }, - { .compatible = "airoha,an7581-pcs-pon", .data = &an7581_pcs_pon }, - { .compatible = "airoha,an7581-pcs-pcie", .data = &an7581_pcs_pcie }, - { .compatible = "airoha,an7581-pcs-usb", .data = &an7581_pcs_usb }, -+ { .compatible = "airoha,an7583-pcs-eth", .data = &an7583_pcs_eth }, -+ { .compatible = "airoha,an7583-pcs-pon", .data = &an7583_pcs_pon }, -+ { .compatible = "airoha,an7583-pcs-pcie", .data = &an7583_pcs_pcie }, -+ { .compatible = "airoha,an7583-pcs-usb", .data = &an7583_pcs_usb }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, airoha_pcs_of_table); ---- a/drivers/net/pcs/airoha/pcs-airoha.h -+++ b/drivers/net/pcs/airoha/pcs-airoha.h -@@ -14,6 +14,9 @@ - #define AIROHA_SCU_PDIDR 0x5c - #define AIROHA_SCU_PRODUCT_ID GENMASK(15, 0) - #define AIROHA_SCU_WAN_CONF 0x70 -+#define AIROHA_SCU_ETH_MAC_SEL BIT(24) -+#define AIROHA_SCU_ETH_MAC_SEL_XFI FIELD_PREP_CONST(AIROHA_SCU_ETH_MAC_SEL, 0x0) -+#define AIROHA_SCU_ETH_MAC_SEL_PON FIELD_PREP_CONST(AIROHA_SCU_ETH_MAC_SEL, 0x1) - #define AIROHA_SCU_WAN_SEL GENMASK(7, 0) - #define AIROHA_SCU_WAN_SEL_SGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x10) - #define AIROHA_SCU_WAN_SEL_HSGMII FIELD_PREP_CONST(AIROHA_SCU_WAN_SEL, 0x11) -@@ -87,8 +90,14 @@ - /* HSGMII_PCS */ - #define AIROHA_PCS_HSGMII_PCS_CTROL_1 0x0 - #define AIROHA_PCS_TBI_10B_MODE BIT(30) -+#define AIROHA_PCS_SGMIII_ENA BIT(27) -+#define AIROHA_PCS_SD_SIG_DET BIT(26) - #define AIROHA_PCS_SGMII_SEND_AN_ERR_EN BIT(24) -+#define AIROHA_PCS_SGMII_1US_TIMER GENMASK(23, 16) -+#define AIROHA_PCS_RX_CLK_ENA BIT(15) -+#define AIROHA_PCS_GMII_TXCLK_ENA BIT(14) - #define AIROHA_PCS_REMOTE_FAULT_DIS BIT(12) -+#define AIROHA_PCS_AN_ENABLE BIT(10) - #define AIROHA_PCS_HSGMII_PCS_CTROL_3 0x8 - #define AIROHA_PCS_HSGMII_PCS_LINK_STSTIME GENMASK(19, 0) - #define AIROHA_PCS_HSGMII_PCS_CTROL_6 0x14 -@@ -192,6 +201,9 @@ - #define AIROHA_PCS_P0_SGMII_IS_10 BIT(2) - #define AIROHA_PCS_P0_SGMII_IS_100 BIT(1) - #define AIROHA_PCS_P0_SGMII_IS_1000 BIT(0) -+#define AIROHA_PCS_MULTI_SGMII_MSG_RX_LIK_STS_1 0x518 -+#define AIROHA_PCS_PAUSE_STS_P2 BIT(6) -+#define AIROHA_PCS_PAUSE_STS_P1 BIT(5) - - /* HSGMII_RATE_ADP */ - #define AIROHA_PCS_HSGMII_RATE_ADAPT_CTRL_0 0x0 -@@ -287,6 +299,8 @@ - #define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_6 0x31c - #define AIROHA_PCS_USXGMII_TOG_PCS_AUTONEG_STS BIT(0) - #define AIROHA_PCS_USXGMII_PCS_AN_CONTROL_7 0x320 -+#define AIROHA_PCS_USXGMII_XFI_MODE_TX_SEL BIT(20) -+#define AIROHA_PCS_USXGMII_XFI_MODE_RX_SEL BIT(16) - #define AIROHA_PCS_USXGMII_RATE_UPDATE_MODE BIT(12) - #define AIROHA_PCS_USXGMII_MODE GENMASK(10, 8) - #define AIROHA_PCS_USXGMII_MODE_10000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x0) -@@ -294,9 +308,27 @@ - #define AIROHA_PCS_USXGMII_MODE_2500 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x2) - #define AIROHA_PCS_USXGMII_MODE_1000 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x3) - #define AIROHA_PCS_USXGMII_MODE_100 FIELD_PREP_CONST(AIROHA_PCS_USXGMII_MODE, 0x4) -+#define AN7583_PCS_USXGMII_RTL_MODIFIED 0x334 -+#define AIROHA_PCS_USXGMII_MODIFIED_RX_GB_OUT_VLD BIT(25) - - /* PMA_PHYA */ - #define AIROHA_PCS_ANA_PXP_CMN_EN 0x0 -+#define AIROHA_PCS_ANA_CMN_VREFSEL GENMASK(18, 16) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_8V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x0) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_8_25V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x1) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_8_5V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x2) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_8_75V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x3) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_9V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x4) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_9_25V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x5) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_9_5V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x6) -+#define AIROHA_PCS_ANA_CMN_VREFSEL_9_75V FIELD_PREP_CONST(AIROHA_PCS_ANA_CMN_VREFSEL, 0x7) -+#define AIROHA_PCS_ANA_CMN_VREFSEL GENMASK(18, 16) -+/* GENMASK(2, 0) input selection from 0 to 7 -+ * BIT(3) OPAMP and path EN -+ * BIT(4) Current path measurement -+ * BIT(5) voltage/current path to PAD -+ */ -+#define AIROHA_PCS_ANA_CMN_MPXSELTOP_DC GENMASK(13, 8) - #define AIROHA_PCS_ANA_CMN_EN BIT(0) - #define AIROHA_PCS_ANA_PXP_JCPLL_IB_EXT_EN 0x4 - #define AIROHA_PCS_ANA_JCPLL_CHP_IOFST GENMASK(29, 24) -@@ -389,6 +421,8 @@ - #define AIROHA_PCS_ANA_JCPLL_TCL_KBAND_VREF GENMASK(20, 16) - #define AIROHA_PCS_ANA_JCPLL_SPARE_L GENMASK(15, 8) - #define AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO BIT(5) -+#define AIROHA_PCS_ANA_PXP_JCPLL_FREQ_MEAS_EN 0x4c -+#define AIROHA_PCS_ANA_TXPLL_IB_EXT_EN BIT(24) - #define AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS 0x50 - #define AIROHA_PCS_ANA_TXPLL_LPF_BC GENMASK(28, 24) - #define AIROHA_PCS_ANA_TXPLL_LPF_BR GENMASK(20, 16) -@@ -412,6 +446,9 @@ - #define AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_1 0x3 - #define AIROHA_PCS_ANA_TXPLL_POSTDIV_EN BIT(8) - #define AIROHA_PCS_ANA_TXPLL_KBAND_KS GENMASK(1, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_PHY_CK1_EN 0x60 -+#define AIROHA_PCS_ANA_TXPLL_PHY_CK2_EN BIT(8) -+#define AIROHA_PCS_ANA_TXPLL_PHY_CK1_EN BIT(0) - #define AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL 0x64 - #define AIROHA_PCS_ANA_TXPLL_PLL_RSTB BIT(24) - #define AIROHA_PCS_ANA_TXPLL_RST_DLY GENMASK(18, 16) -@@ -477,16 +514,41 @@ - #define AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT GENMASK(25, 24) - #define AIROHA_PCS_ANA_TXPLL_LDO_OUT GENMASK(17, 16) - #define AIROHA_PCS_ANA_TXPLL_SSC_PERIOD GENMASK(15, 0) -+#define AIROHA_PCS_ANA_PXP_TXPLL_VTP_EN 0x88 -+#define AIROHA_PCS_ANA_TXPLL_VTP GENMASK(10, 8) -+#define AIROHA_PCS_ANA_TXPLL_VTP_EN BIT(0) - #define AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF 0x94 -+#define AIROHA_PCS_ANA_TXPLL_POSTDIV_D256_EN BIT(25) /* 0: 128 1: 256 */ -+#define AIROHA_PCS_ANA_TXPLL_VCO_KBAND_MEAS_EN BIT(24) -+#define AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN BIT(16) -+#define AIROHA_PCS_ANA_TXPLL_VREF_SEL BIT(8) -+#define AIROHA_PCS_ANA_TXPLL_VREF_SEL_VBG FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VREF_SEL, 0x0) -+#define AIROHA_PCS_ANA_TXPLL_VREF_SEL_AVDD FIELD_PREP_CONST(AIROHA_PCS_ANA_TXPLL_VREF_SEL, 0x1) - #define AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF GENMASK(4, 0) -+#define AN7583_PCS_ANA_PXP_TXPLL_CHP_DOUBLE_EN 0x98 -+#define AIROHA_PCS_ANA_TXPLL_SPARE_L BIT(0) /* ICHP_DOUBLE */ -+#define AIROHA_PCS_ANA_PXP_PLL_MONCLK_SEL 0xa0 -+#define AIROHA_PCS_ANA_TDC_AUTOEN BIT(24) -+#define AIROHA_PCS_ANA_PXP_TDC_SYNC_CK_SEL 0xa8 -+#define AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL GENMASK(17, 16) -+#define AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN BIT(8) -+#define AIROHA_PCS_ANA_PXP_TX_TXLBRC_EN 0xc0 -+#define AIROHA_PCS_ANA_TX_TERMCAL_VREF_L GENMASK(26, 24) -+#define AIROHA_PCS_ANA_TX_TERMCAL_VREF_H GENMASK(18, 16) - #define AIROHA_PCS_ANA_PXP_TX_CKLDO_EN 0xc4 - #define AIROHA_PCS_ANA_TX_DMEDGEGEN_EN BIT(24) - #define AIROHA_PCS_ANA_TX_CKLDO_EN BIT(0) -+#define AIROHA_PCS_ANA_PXP_TX_TERMCAL_SELPN 0xc8 -+#define AIROHA_PCS_ANA_TX_TDC_CK_SEL GENMASK(17, 16) - #define AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL 0xcc - #define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE BIT(24) - #define AIROHA_PCS_ANA_RX_PHY_CK_SEL BIT(16) - #define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_PR 0x0 - #define AIROHA_PCS_ANA_RX_PHY_CK_SEL_FROM_DES 0x1 -+#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE BIT(8) -+#define AIROHA_PCS_ANA_RX_BUSBIT_SEL BIT(0) -+#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_8BIT FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_BUSBIT_SEL, 0x0) -+#define AIROHA_PCS_ANA_RX_BUSBIT_SEL_16BIT FIELD_PREP_CONST(AIROHA_PCS_ANA_RX_BUSBIT_SEL, 0x1) - #define AIROHA_PCS_ANA_PXP_RX_REV_0 0xd4 - #define AIROHA_PCS_ANA_RX_REV_1 GENMASK(31, 16) - #define AIROHA_PCS_ANA_REV_1_FE_EQ_BIAS_CTRL GENMASK(30, 28) -@@ -494,6 +556,16 @@ - #define AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL GENMASK(22, 20) - #define AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK GENMASK(19, 18) - #define AIROHA_PCS_ANA_REV_1_FECUR_PWDB BIT(16) -+#define AIROHA_PCS_ANA_RX_REV_0 GENMASK(15, 0) -+#define AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE GENMASK(13, 12) -+#define AIROHA_PCS_ANA_REV_0_OSCAL_FE_MODE_SET_SEL BIT(11) -+#define AIROHA_PCS_ANA_REV_0_FE_EQ_GAIN_MODE_TRAINING BIT(10) -+#define AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_TRAINING GENMASK(9, 8) -+#define AIROHA_PCS_ANA_REV_0_FE_EQ_GAIN_MODE_NORMAL BIT(6) -+#define AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL GENMASK(5, 4) -+#define AIROHA_PCS_ANA_REV_0_VOS_PNINV GENMASK(3, 2) -+#define AIROHA_PCS_ANA_REV_0_PLEYEBD4 BIT(1) -+#define AIROHA_PCS_ANA_REV_0_PLEYE_XOR_MON_EN BIT(0) - #define AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV 0xd8 - #define AIROHA_PCS_ANA_RX_TDC_CK_SEL BIT(24) - #define AIROHA_PCS_ANA_RX_PHYCK_RSTB BIT(16) -@@ -502,6 +574,8 @@ - #define AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV 0xdc - #define AIROHA_PCS_ANA_CDR_PD_EDGE_DIS BIT(8) - #define AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV BIT(0) -+#define AIROHA_PCS_ANA_PXP_CDR_LPF_BOT_LIM 0xe0 -+#define AIROHA_PCS_ANA_CDR_LPF_BOT_LIM GENMASK(18, 0) - #define AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO 0xe8 - #define AIROHA_PCS_ANA_CDR_LPF_TOP_LIM GENMASK(26, 8) - #define AIROHA_PCS_ANA_CDR_LPF_RATIO GENMASK(1, 0) -@@ -517,6 +591,19 @@ - #define AIROHA_PCS_ANA_CDR_PR_DAC_BAND GENMASK(20, 16) - #define AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL GENMASK(10, 8) - #define AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL GENMASK(2, 0) -+#define AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV 0x100 -+#define AIROHA_PCS_ANA_CDR_PR_RSTB_BYPASS BIT(16) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV GENMASK(1, 0) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x0) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x1) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x2) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_X FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, 0x3) -+#define AIROHA_PCS_ANA_PXP_CDR_PR_TDC_REF_SEL 0x108 -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1 GENMASK(25, 24) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_1 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x0) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_2 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x1) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_4 FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x2) -+#define AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_X FIELD_PREP_CONST(AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, 0x3) - #define AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN 0x10c - #define AIROHA_PCS_ANA_RX_DAC_MON GENMASK(28, 24) - #define AIROHA_PCS_ANA_CDR_PR_CAP_EN BIT(19) -@@ -526,6 +613,7 @@ - #define AIROHA_PCS_ANA_CDR_PR_MONPR_EN BIT(0) - #define AIROHA_PCS_ANA_PXP_RX_DAC_RANGE 0x110 - #define AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL GENMASK(25, 24) -+#define AIROHA_PCS_ANA_RX_DAC_RANGE_EYE GENMASK(9, 8) - #define AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH 0x114 - #define AIROHA_PCS_ANA_RX_FE_50OHMS_SEL GENMASK(25, 24) - #define AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL GENMASK(20, 16) -@@ -964,7 +1052,70 @@ - #define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0 0x0 - #define AIROHA_PCS_PMA_SW_LCPLL_EN BIT(24) - #define AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1 0x4 -+#define AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER GENMASK(31, 24) -+#define AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER GENMASK(23, 16) -+#define AIROHA_PCS_PMA_LCPLL_EN_TIMER GENMASK(15, 8) - #define AIROHA_PCS_PMA_LCPLL_MAN_PWDB BIT(0) -+#define AIROHA_PCS_PMA_LCPLL_TDC_PW_0 0x10 -+#define AIROHA_PCS_PMA_LCPLL_TDC_DIG_PWDB BIT(0) -+#define AIROHA_PCS_PMA_LCPLL_TDC_PW_5 0x24 -+#define AIROHA_PCS_PMA_LCPLL_TDC_SYNC_IN_MODE BIT(24) -+#define AIROHA_PCS_PMA_LCPLL_AUTOK_TDC BIT(16) -+#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_0 0x28 -+#define AIROHA_PCS_PMA_LCPLL_KI GENMASK(10, 8) -+#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC GENMASK(1, 0) -+#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_32 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x0) -+#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_16 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x1) -+#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x2) -+#define AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_PON_RX_CDR_DIVTDC, 0x3) -+#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_1 0x2c -+#define AIROHA_PCS_PMA_LCPLL_A_TDC GENMASK(11, 8) -+#define AIROHA_PCS_PMA_LCPLL_GPON_SEL BIT(0) -+#define AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_EPON FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_GPON_SEL, 0x0) -+#define AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_GPON FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_GPON_SEL, 0x1) -+#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_3 0x34 -+#define AIROHA_PCS_PMA_LCPLL_NCPO_LOAD BIT(8) -+#define AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT GENMASK(1, 0) -+#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_5 0x3c -+#define AIROHA_PCS_PMA_LCPLL_TDC_AUTOPW_NCPO BIT(16) -+#define AIROHA_PCS_PMA_LCPLL_TDC_FLT_6 0x40 -+#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY GENMASK(9, 8) -+#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x0) -+#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D1 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x1) -+#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D2 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x2) -+#define AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY_SEL_D3 FIELD_PREP_CONST(AIROHA_PCS_PMA_LCPLL_NCPO_CHG_DELAY, 0x3) -+#define AIROHA_PCS_PMA_LCPLL_TDC_PCW_1 0x48 -+#define AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0) -+#define AIROHA_PCS_PMA_LCPLL_TDC_PCW_2 0x4c -+#define AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON GENMASK(30, 0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0 0x68 -+#define AIROHA_PCS_PMA_X_MAX GENMASK(26, 16) -+#define AIROHA_PCS_PMA_X_MIN GENMASK(10, 0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1 0x6c -+#define AIROHA_PCS_PMA_INDEX_MODE BIT(16) -+#define AIROHA_PCS_PMA_Y_MAX GENMASK(14, 8) -+#define AIROHA_PCS_PMA_Y_MIN GENMASK(6, 0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2 0x70 -+#define AIROHA_PCS_PMA_EYEDUR GENMASK(19, 0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3 0x74 -+#define AIROHA_PCS_PMA_EYE_NEXTPTS BIT(16) -+#define AIROHA_PCS_PMA_EYE_NEXTPTS_TOGGLE BIT(8) -+#define AIROHA_PCS_PMA_EYE_NEXTPTS_SEL BIT(0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0 0x78 -+#define AIROHA_PCS_PMA_EYECNT_VTH GENMASK(15, 8) -+#define AIROHA_PCS_PMA_EYECNT_HTH GENMASK(7, 0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1 0x7c -+#define AIROHA_PCS_PMA_EO_VTH GENMASK(23, 16) -+#define AIROHA_PCS_PMA_EO_HTH GENMASK(10, 0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0 0x80 -+#define AIROHA_PCS_PMA_EYE_MASK GENMASK(31, 24) -+#define AIROHA_PCS_PMA_CNTFOREVER BIT(16) -+#define AIROHA_PCS_PMA_CNTLEN GENMASK(9, 0) -+#define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1 0x84 -+#define AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B BIT(24) -+#define AIROHA_PCS_PMA_FORCE_EYEDUR_EN BIT(16) -+#define AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B BIT(8) -+#define AIROHA_PCS_PMA_DISB_EYEDUR_EN BIT(0) - #define AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2 0x88 - #define AIROHA_PCS_PMA_DATA_SHIFT BIT(8) - #define AIROHA_PCS_PMA_EYECNT_FAST BIT(0) -@@ -996,14 +1147,49 @@ - #define AIROHA_PCS_PMA_RX_BLWC_RDY_EN GENMASK(15, 0) - #define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6 0x104 - #define AIROHA_PCS_PMA_RX_OS_END GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0 0x108 -+#define AIROHA_PCS_PMA_DISB_RX_FEOS_EN BIT(24) -+#define AIROHA_PCS_PMA_DISB_RX_PDOS_EN BIT(16) -+#define AIROHA_PCS_PMA_DISB_RX_PICAL_EN BIT(8) -+#define AIROHA_PCS_PMA_DISB_RX_OS_EN BIT(0) - #define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1 0x10c - #define AIROHA_PCS_PMA_DISB_RX_RDY BIT(24) -+#define AIROHA_PCS_PMA_DISB_RX_BLWC_EN BIT(16) -+#define AIROHA_PCS_PMA_DISB_RX_OS_RDY BIT(8) -+#define AIROHA_PCS_PMA_DISB_RX_SDCAL_EN BIT(0) -+#define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0 0x110 -+#define AIROHA_PCS_PMA_FORCE_RX_FEOS_EN BIT(24) -+#define AIROHA_PCS_PMA_FORCE_RX_PDOS_EN BIT(16) -+#define AIROHA_PCS_PMA_FORCE_RX_PICAL_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_RX_OS_EN BIT(0) - #define AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1 0x114 - #define AIROHA_PCS_PMA_FORCE_RX_RDY BIT(24) -+#define AIROHA_PCS_PMA_FORCE_RX_BLWC_EN BIT(16) -+#define AIROHA_PCS_PMA_FORCE_RX_OS_RDY BIT(8) -+#define AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN BIT(0) -+#define AIROHA_PCS_PMA_PHY_EQ_CTRL_0 0x118 -+#define AIROHA_PCS_PMA_VEO_MASK GENMASK(31, 24) -+#define AIROHA_PCS_PMA_HEO_MASK GENMASK(18, 8) -+#define AIROHA_PCS_PMA_EQ_EN_DELAY GENMASK(7, 0) -+#define AIROHA_PCS_PMA_PHY_EQ_CTRL_1 0x11c -+#define AIROHA_PCS_PMA_B_ZERO_SEL BIT(24) -+#define AIROHA_PCS_PMA_HEO_EMPHASIS BIT(16) -+#define AIROHA_PCS_PMA_A_MGAIN BIT(8) -+#define AIROHA_PCS_PMA_A_LGAIN BIT(0) - #define AIROHA_PCS_PMA_PHY_EQ_CTRL_2 0x120 - #define AIROHA_PCS_PMA_EQ_DEBUG_SEL GENMASK(17, 16) - #define AIROHA_PCS_PMA_FOM_NUM_ORDER GENMASK(12, 8) - #define AIROHA_PCS_PMA_A_SEL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_SS_RX_FEOS 0x144 -+#define AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE BIT(8) -+#define AIROHA_PCS_PMA_LFSEL GENMASK(7, 0) -+#define AIROHA_PCS_PMA_SS_RX_BLWC 0x148 -+#define AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM GENMASK(29, 23) -+#define AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM GENMASK(22, 16) -+#define AIROHA_PCS_PMA_EQ_BLWC_GAIN GENMASK(11, 8) -+#define AIROHA_PCS_PMA_EQ_BLWC_POL BIT(0) -+#define AIROHA_PCS_PMA_EQ_BLWC_POL_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_EQ_BLWC_POL, 0x0) -+#define AIROHA_PCS_PMA_EQ_BLWC_POL_INVERSION FIELD_PREP_CONST(AIROHA_PCS_PMA_EQ_BLWC_POL, 0x1) - #define AIROHA_PCS_PMA_SS_RX_FREQ_DET_1 0x14c - #define AIROHA_PCS_PMA_UNLOCK_CYCLECNT GENMASK(31, 16) - #define AIROHA_PCS_PMA_LOCK_CYCLECNT GENMASK(15, 0) -@@ -1022,31 +1208,182 @@ - #define AIROHA_PCS_PMA_FREQLOCK_DET_EN_WAIT FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x2) - #define AIROHA_PCS_PMA_FREQLOCK_DET_EN_NORMAL FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x3) - #define AIROHA_PCS_PMA_FREQLOCK_DET_EN_RX_STATE FIELD_PREP_CONST(AIROHA_PCS_PMA_FREQLOCK_DET_EN, 0x7) -+#define AIROHA_PCS_PMA_RX_PI_CAL 0x15c -+#define AIROHA_PCS_PMA_KPGAIN GENMASK(10, 8) -+#define AIROHA_PCS_PMA_RX_CAL1 0x160 -+#define AIROHA_PCS_PMA_CAL_CYC GENMASK(25, 24) -+#define AIROHA_PCS_PMA_CAL_CYC_63 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x0) -+#define AIROHA_PCS_PMA_CAL_CYC_15 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x1) -+#define AIROHA_PCS_PMA_CAL_CYC_31 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x2) -+#define AIROHA_PCS_PMA_CAL_CYC_127 FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_CYC, 0x3) -+#define AIROHA_PCS_PMA_CAL_STB GENMASK(17, 16) -+#define AIROHA_PCS_PMA_CAL_STB_5US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x0) -+#define AIROHA_PCS_PMA_CAL_STB_8US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x1) -+#define AIROHA_PCS_PMA_CAL_STB_16US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x2) -+#define AIROHA_PCS_PMA_CAL_STB_32US FIELD_PREP_CONST(AIROHA_PCS_PMA_CAL_STB, 0x3) -+#define AIROHA_PCS_PMA_CAL_1US_SET GENMASK(15, 8) -+#define AIROHA_PCS_PMA_SIM_FAST_EN BIT(0) -+#define AIROHA_PCS_PMA_RX_CAL2 0x164 -+#define AIROHA_PCS_PMA_CAL_CYC_TIME GENMASK(17, 16) -+#define AIROHA_PCS_PMA_CAL_OUT_OS GENMASK(11, 8) -+#define AIROHA_PCS_PMA_CAL_OS_PULSE BIT(0) - #define AIROHA_PCS_PMA_SS_RX_SIGDET_1 0x16c - #define AIROHA_PCS_PMA_SIGDET_EN BIT(0) -+#define AIROHA_PCS_PMA_RX_FLL_0 0x170 -+#define AIROHA_PCS_PMA_KBAND_KFC GENMASK(25, 24) -+#define AIROHA_PCS_PMA_KBAND_KFC_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x0) -+#define AIROHA_PCS_PMA_KBAND_KFC_16 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x1) -+#define AIROHA_PCS_PMA_KBAND_KFC_32 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x2) -+#define AIROHA_PCS_PMA_KBAND_KFC_64 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_KFC, 0x3) -+#define AIROHA_PCS_PMA_FPKDIV GENMASK(18, 8) -+#define AIROHA_PCS_PMA_KBAND_PREDIV GENMASK(2, 0) -+#define AIROHA_PCS_PMA_KBAND_PREDIV_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x0) -+#define AIROHA_PCS_PMA_KBAND_PREDIV_2 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x1) -+#define AIROHA_PCS_PMA_KBAND_PREDIV_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x2) -+#define AIROHA_PCS_PMA_KBAND_PREDIV_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_KBAND_PREDIV, 0x3) - #define AIROHA_PCS_PMA_RX_FLL_1 0x174 -+#define AIROHA_PCS_PMA_SYMBOL_WD GENMASK(26, 24) -+#define AIROHA_PCS_PMA_SETTLE_TIME_SEL GENMASK(18, 16) - #define AIROHA_PCS_PMA_LPATH_IDAC GENMASK(10, 0) - #define AIROHA_PCS_PMA_RX_FLL_2 0x178 - #define AIROHA_PCS_PMA_CK_RATE GENMASK(18, 16) - #define AIROHA_PCS_PMA_CK_RATE_20 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x0) - #define AIROHA_PCS_PMA_CK_RATE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x1) - #define AIROHA_PCS_PMA_CK_RATE_5 FIELD_PREP_CONST(AIROHA_PCS_PMA_CK_RATE, 0x2) -+#define AIROHA_PCS_PMA_AMP GENMASK(10, 8) -+#define AIROHA_PCS_PMA_PRBS_SEL GENMASK(2, 0) - #define AIROHA_PCS_PMA_RX_FLL_5 0x184 - #define AIROHA_PCS_PMA_FLL_IDAC_MIN GENMASK(26, 16) - #define AIROHA_PCS_PMA_FLL_IDAC_MAX GENMASK(10, 0) -+#define AIROHA_PCS_PMA_RX_FLL_6 0x188 -+#define AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN BIT(24) -+#define AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN BIT(16) -+#define AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN BIT(8) -+#define AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN BIT(0) - #define AIROHA_PCS_PMA_RX_FLL_B 0x19c - #define AIROHA_PCS_PMA_LOAD_EN BIT(0) -+#define AIROHA_PCS_PMA_RX_PDOS_CTRL_0 0x200 -+#define AIROHA_PCS_PMA_SAP_SEL GENMASK(18, 16) -+#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x0) -+#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_7 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x1) -+#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_8 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x2) -+#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_9 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x3) -+#define AIROHA_PCS_PMA_SAP_SEL_SHIFT_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_SAP_SEL, 0x4) -+#define AIROHA_PCS_PMA_EYE_BLWC_ADD BIT(8) -+#define AIROHA_PCS_PMA_DATA_BLWC_ADD BIT(0) -+#define AIROHA_PCS_PMA_RX_RESET_0 0x204 -+#define AIROHA_PCS_PMA_CAL_RST_B BIT(24) -+#define AIROHA_PCS_PMA_EQ_PI_CAL_RST_B BIT(16) -+#define AIROHA_PCS_PMA_FEOS_RST_B BIT(8) - #define AIROHA_PCS_PMA_RX_RESET_1 0x208 - #define AIROHA_PCS_PMA_SIGDET_RST_B BIT(8) -+#define AIROHA_PCS_PMA_PDOS_RST_B BIT(0) -+#define AIROHA_PCS_PMA_RX_DEBUG_0 0x20c -+#define AIROHA_PCS_PMA_RO_TOGGLE BIT(24) -+#define AIROHA_PCS_PMA_BISTCTL_CONTROL 0x210 -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL GENMASK(4, 0) -+/* AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x0) */ -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS7 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x1) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS9 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x2) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS15 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x3) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS23 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x4) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS31 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x5) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_HFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x6) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_MFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x7) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_4 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x8) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_5_LFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x9) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_6 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xa) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_7 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xb) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_8_LFTP FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xc) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_9 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xd) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_10 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xe) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_SQUARE_11 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0xf) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PROG_80 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x10) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_1 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x11) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_ALL_0 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x12) -+#define AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS11 FIELD_PREP_CONST(AIROHA_PCS_PMA_BISTCTL_PAT_SEL, 0x13) -+#define AIROHA_PCS_PMA_BISTCTL_ALIGN_PAT 0x214 -+#define AIROHA_PCS_PMA_BISTCTL_POLLUTION 0x220 -+#define AIROHA_PCS_PMA_BIST_TX_DATA_POLLUTION_LATCH BIT(16) -+#define AIROHA_PCS_PMA_BISTCTL_PRBS_INITIAL_SEED 0x224 -+#define AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD 0x230 -+#define AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK GENMASK(15, 0) -+#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_2 0x23c -+#define AIROHA_PCS_PMA_PI_CAL_DATA_OUT GENMASK(22, 16) -+#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_5 0x248 -+#define AIROHA_PCS_PMA_VEO_RDY BIT(24) -+#define AIROHA_PCS_PMA_HEO_RDY BIT(16) -+#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_9 0x258 -+#define AIROHA_PCS_PMA_EO_Y_DONE BIT(24) -+#define AIROHA_PCS_PMA_EO_X_DONE BIT(16) -+#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_10 0x25c -+#define AIROHA_PCS_PMA_EYE_EL GENMASK(26, 16) -+#define AIROHA_PCS_PMA_EYE_ER GENMASK(10, 0) - #define AIROHA_PCS_PMA_TX_RST_B 0x260 - #define AIROHA_PCS_PMA_TXCALIB_RST_B BIT(8) - #define AIROHA_PCS_PMA_TX_TOP_RST_B BIT(0) -+#define AIROHA_PCS_PMA_TX_CALIB_0 0x264 -+#define AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL GENMASK(25, 24) -+#define AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN BIT(16) -+#define AIROHA_PCS_PMA_RX_TORGS_DEBUG_11 0x290 -+#define AIROHA_PCS_PMA_EYE_EB GENMASK(14, 8) -+#define AIROHA_PCS_PMA_EYE_EU GENMASK(6, 0) -+#define AIROHA_PCS_PMA_RX_FORCE_MODE_0 0x294 -+#define AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_0 0x300 -+#define AIROHA_PCS_PMA_DISB_DA_XPON_CDR_LPF_RSTB BIT(24) -+#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_GAIN_CTRL BIT(0) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_1 0x304 -+#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E0 BIT(24) -+#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D1 BIT(16) -+#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D0 BIT(8) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_2 0x308 -+#define AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE BIT(24) -+#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_VOS BIT(16) -+#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE BIT(8) -+#define AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E1 BIT(0) -+#define AIROHA_PCS_PMA_RX_FORCE_MODE_3 0x30c -+#define AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY BIT(0) -+#define AIROHA_PCS_PMA_RX_FORCE_MODE_6 0x318 -+#define AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_EYECNT_RDY BIT(0) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_3 0x31c -+#define AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY BIT(0) - #define AIROHA_PCS_PMA_RX_DISB_MODE_4 0x320 - #define AIROHA_PCS_PMA_DISB_BLWC_OFFSET BIT(24) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_5 0x324 -+#define AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN BIT(24) -+#define AIROHA_PCS_PMA_DISB_EYECNT_RDY BIT(16) -+#define AIROHA_PCS_PMA_RX_FORCE_MODE_7 0x328 -+#define AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B BIT(16) -+#define AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB BIT(8) -+#define AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB BIT(0) -+#define AIROHA_PCS_PMA_RX_FORCE_MODE_8 0x32c -+#define AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B BIT(24) -+#define AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B BIT(8) -+#define AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B BIT(0) - #define AIROHA_PCS_PMA_RX_FORCE_MODE_9 0x330 -+#define AIROHA_PCS_PMA_FORCE_EYE_TOP_EN BIT(16) -+#define AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O BIT(8) - #define AIROHA_PCS_PMA_FORCE_FBCK_LOCK BIT(0) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_6 0x334 -+#define AIROHA_PCS_PMA_DISB_PDOS_RX_RST_B BIT(16) -+#define AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB BIT(8) -+#define AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB BIT(0) -+#define AIROHA_PCS_PMA_RX_DISB_MODE_7 0x338 -+#define AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B BIT(24) -+#define AIROHA_PCS_PMA_DISB_FEOS_RX_RST_B BIT(16) -+#define AIROHA_PCS_PMA_DISB_SDCAL_REF_RST_B BIT(8) -+#define AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B BIT(0) - #define AIROHA_PCS_PMA_RX_DISB_MODE_8 0x33c -+#define AIROHA_PCS_PMA_DISB_EYE_TOP_EN BIT(16) -+#define AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O BIT(8) - #define AIROHA_PCS_PMA_DISB_FBCK_LOCK BIT(0) -+#define AIROHA_PCS_PMA_SS_BIST_1 0x344 -+#define AIROHA_PCS_PMA_LNX_BISTCTL_BIT_ERROR_RST_SEL BIT(24) -+#define AIROHA_PCS_PMA_ANLT_PX_LNX_LT_LOS BIT(0) - #define AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0 0x34c - #define AIROHA_PCS_PMA_XPON_CDR_PD_PWDB BIT(24) - #define AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB BIT(16) -@@ -1069,7 +1406,11 @@ - #define AIROHA_PCS_PMA_PLL_LOCK_TARGET_BEG GENMASK(15, 0) - #define AIROHA_PCS_PMA_PLL_TDC_FREQDET_3 0x39c - #define AIROHA_PCS_PMA_PLL_LOCK_LOCKTH GENMASK(11, 8) -+#define AIROHA_PCS_PMA_ADD_CLKPATH_RST_0 0x410 -+#define AIROHA_PCS_PMA_CLKPATH_RSTB_CK BIT(8) -+#define AIROHA_PCS_PMA_CLKPATH_RST_EN BIT(0) - #define AIROHA_PCS_PMA_ADD_XPON_MODE_1 0x414 -+#define AIROHA_PCS_PMA_TX_BIST_GEN_EN BIT(16) - #define AIROHA_PCS_PMA_XFI_RX_MODE GENMASK(11, 9) - #define AIROHA_PCS_PMA_XFI_RX_MODE_10G3 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x0) - #define AIROHA_PCS_PMA_XFI_RX_MODE_5G15 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_RX_MODE, 0x1) -@@ -1085,7 +1426,26 @@ - #define AIROHA_PCS_PMA_XFI_TX_MODE_2G57 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x3) - #define AIROHA_PCS_PMA_XFI_TX_MODE_3G12 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x4) - #define AIROHA_PCS_PMA_XFI_TX_MODE_1G25 FIELD_PREP_CONST(AIROHA_PCS_PMA_XFI_TX_MODE, 0x5) -+#define AIROHA_PCS_PMA_ADD_RX2ANA_1 0x424 -+#define AIROHA_PCS_PMA_RX_DAC_E0 GENMASK(30, 24) -+#define AIROHA_PCS_PMA_RX_DAC_D1 GENMASK(22, 16) -+#define AIROHA_PCS_PMA_RX_DAC_D0 GENMASK(14, 8) -+#define AIROHA_PCS_PMA_RX_DAC_EYE GENMASK(6, 0) -+#define AIROHA_PCS_PMA_ADD_RX2ANA_2 0x428 -+#define AIROHA_PCS_PMA_RX_FEOS_OUT GENMASK(13, 8) -+#define AIROHA_PCS_PMA_RX_DAC_E1 GENMASK(6, 0) -+#define AIROHA_PCS_PMA_PON_TX_COUNTER_0 0x440 -+#define AIROHA_PCS_PMA_TXCALIB_5US GENMASK(31, 16) -+#define AIROHA_PCS_PMA_TXCALIB_50US GENMASK(15, 0) -+#define AIROHA_PCS_PMA_PON_TX_COUNTER_1 0x444 -+#define AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT GENMASK(31, 16) -+#define AIROHA_PCS_PMA_TX_CK_EN_WAIT GENMASK(15, 0) -+#define AIROHA_PCS_PMA_PON_TX_COUNTER_2 0x448 -+#define AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT GENMASK(31, 16) -+#define AIROHA_PCS_PMA_TX_POWER_ON_WAIT GENMASK(15, 0) - #define AIROHA_PCS_PMA_SW_RST_SET 0x460 -+#define AIROHA_PCS_PMA_SW_XFI_RXMAC_RST_N BIT(17) -+#define AIROHA_PCS_PMA_SW_XFI_TXMAC_RST_N BIT(16) - #define AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N BIT(11) - #define AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N BIT(10) - #define AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N BIT(9) -@@ -1098,17 +1458,32 @@ - #define AIROHA_PCS_PMA_SW_TX_RST_N BIT(2) - #define AIROHA_PCS_PMA_SW_RX_RST_N BIT(1) - #define AIROHA_PCS_PMA_SW_RX_FIFO_RST_N BIT(0) -+#define AIROHA_PCS_PMA_TX_DLY_CTRL 0x468 -+#define AIROHA_PCS_PMA_OUTBEN_DATA_MODE GENMASK(30, 28) -+#define AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE GENMASK(23, 16) -+#define AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE GENMASK(14, 8) -+#define AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE GENMASK(6, 0) - #define AIROHA_PCS_PMA_XPON_INT_EN_3 0x474 - #define AIROHA_PCS_PMA_RX_SIGDET_INT_EN BIT(16) - #define AIROHA_PCS_PMA_XPON_INT_STA_3 0x47c - #define AIROHA_PCS_PMA_RX_SIGDET_INT BIT(16) - #define AIROHA_PCS_PMA_RX_EXTRAL_CTRL 0x48c -+/* 4ref_ck step: -+ * - 0x1 4ref_ck -+ * - 0x2 8ref_ck -+ * - 0x3 12ref_ck -+ * ... -+ */ -+#define AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME GENMASK(15, 8) -+#define AIROHA_PCS_PMA_OS_RDY_LATCH BIT(1) - #define AIROHA_PCS_PMA_DISB_LEQ BIT(0) - #define AIROHA_PCS_PMA_RX_FREQDET 0x530 - #define AIROHA_PCS_PMA_FL_OUT GENMASK(31, 16) - #define AIROHA_PCS_PMA_FBCK_LOCK BIT(0) - #define AIROHA_PCS_PMA_XPON_TX_RATE_CTRL 0x580 - #define AIROHA_PCS_PMA_PON_TX_RATE_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_MD32_MEM_CLK_CTRL 0x60c -+#define AIROHA_PCS_PMA_MD32PM_CK_SEL GENMASK(31, 0) - #define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN 0x768 - #define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL BIT(24) - #define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL GENMASK(19, 16) -@@ -1131,8 +1506,13 @@ - #define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 BIT(8) - #define AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1 GENMASK(5, 0) - #define AIROHA_PCS_PMA_PXP_TX_RATE_CTRL 0x784 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE GENMASK(22, 16) - #define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL BIT(8) - #define AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL GENMASK(1, 0) -+#define AIROHA_PCS_PMA_PXP_CDR_PR_FLL_COR 0x790 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_DAC_EYE BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE GENMASK(22, 16) - #define AIROHA_PCS_PMA_PXP_CDR_PR_IDAC 0x794 - #define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW BIT(24) - #define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_IDAC BIT(16) -@@ -1152,6 +1532,9 @@ - #define AIROHA_PCS_PMA_PXP_AEQ_RSTB 0x814 - #define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL BIT(24) - #define AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL BIT(16) -+#define AIROHA_PCS_PMA_PXP_AEQ_EN 0x808 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_AEQ_EN BIT(0) - #define AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA 0x818 - #define AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB BIT(24) - #define AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB BIT(16) -@@ -1177,6 +1560,14 @@ - #define AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN BIT(16) - #define AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_CKOUT_EN BIT(8) - #define AIROHA_PCS_PMA_FORCE_DA_JCPLL_CKOUT_EN BIT(0) -+#define AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB 0x83c -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON BIT(16) -+#define AIROHA_PCS_PMA_PXP_RX_OSCAL_EN 0x840 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB BIT(24) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB BIT(16) -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN BIT(0) - #define AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B 0x84c - #define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB BIT(24) - #define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB BIT(16) -@@ -1187,6 +1578,12 @@ - #define AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN BIT(16) - #define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN BIT(8) - #define AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN BIT(0) -+#define AIROHA_PCS_PMA_PXP_TXPLL_KBAND_LOAD_EN 0x858 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_KBAND_LOAD_EN BIT(0) -+#define AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG 0x864 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW_CHG BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG BIT(0) - #define AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN 0x874 - #define AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL BIT(24) - #define AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL BIT(16) -@@ -1198,6 +1595,14 @@ - #define AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN BIT(16) - #define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB BIT(8) - #define AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB BIT(0) -+#define AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN 0x898 -+#define AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN BIT(8) -+#define AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN BIT(0) -+#define AIROHA_PCS_PMA_DIG_RESERVE_12 0x8b8 -+#define AIROHA_PCS_PMA_RESERVE_12_FEOS_0 BIT(0) -+#define AIROHA_PCS_PMA_DIG_RESERVE_24 0x8fc -+#define AIROHA_PCS_PMA_FORCE_RX_GEARBOX BIT(12) -+#define AIROHA_PCS_PMA_FORCE_SEL_RX_GEARBOX BIT(8) - #define AIROHA_PCS_PMA_DIG_RESERVE_29 0x910 - #define AIROHA_PCS_PMA_2L_TX_RATE_CTRL GENMASK(1, 0) - #define AIROHA_PCS_PMA_2L_RX_RATE_CTRL GENMASK(5, 4) -@@ -1205,6 +1610,19 @@ - #define AIROHA_PCS_MAX_CALIBRATION_TRY 50 - #define AIROHA_PCS_MAX_NUM_RSTS 2 - -+enum pon_eo_buf_vals { -+ EYE_EU, -+ EYE_EB, -+ DAC_D0, -+ DAC_D1, -+ DAC_E0, -+ DAC_E1, -+ DAC_EYE, -+ FEOS, -+ -+ EO_BUF_MAX, -+}; -+ - enum xfi_port_type { - AIROHA_PCS_ETH, - AIROHA_PCS_PON, -@@ -1254,6 +1672,11 @@ struct airoha_pcs_match_data { - int num_port; - enum xfi_port_type port_type; - -+ bool hibernation_workaround; -+ bool usxgmii_ber_time_fixup; -+ bool usxgmii_rx_gb_out_vld_tweak; -+ bool usxgmii_xfi_mode_sel; -+ - int (*alloc_regmap_fields)(struct airoha_pcs_priv *priv); - int (*bringup)(struct airoha_pcs_priv *priv, - int index, phy_interface_t interface); -@@ -1307,3 +1730,30 @@ static inline int an7581_pcs_rxlock_work - return 0; - } - #endif -+ -+#ifdef CONFIG_PCS_AIROHA_AN7583 -+int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface); -+ -+int an7583_pcs_usb_phya_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface); -+ -+void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv, int index); -+#else -+static inline int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int an7583_pcs_usb_phya_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv, -+ int index) -+{ -+} -+#endif ---- /dev/null -+++ b/drivers/net/pcs/airoha/pcs-an7583.c -@@ -0,0 +1,2349 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2024 AIROHA Inc -+ * Author: Christian Marangi -+ */ -+#include -+#include -+#include -+ -+#include "pcs-airoha.h" -+ -+static void an7583_pcs_dig_reset_hold(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N | -+ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_REF_RST_N); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_ALLPCS_RST_N); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_TX_RST_N | -+ AIROHA_PCS_PMA_SW_RX_RST_N); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_PMA_RST_N); -+ -+ usleep_range(50, 100); -+} -+ -+static void an7583_pcs_dig_reset_release(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_REF_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_TX_RST_N | -+ AIROHA_PCS_PMA_SW_RX_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_PMA_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N | -+ AIROHA_PCS_PMA_SW_TX_FIFO_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_ALLPCS_RST_N); -+ -+ usleep_range(100, 200); -+} -+ -+static void an7583_pcs_common_phya_txpll(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 pcw, tdc_pcw; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: /* DS(RX)_1.25G / US(TX)_1.25G*/ -+ case PHY_INTERFACE_MODE_1000BASEX: -+ pcw = 0x32000000; -+ tdc_pcw = 0x64000000; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: /* DS(RX)_3.125G / US(TX)_3.125G */ -+ pcw = 0x3e800000; -+ tdc_pcw = 0x7d000000; -+ break; -+ case PHY_INTERFACE_MODE_5GBASER: /* DS(RX)_5.15625G / US(TX)_5.15625G */ -+ case PHY_INTERFACE_MODE_USXGMII: /* DS(RX)_10.31252G / US(TX)_10.3125G */ -+ case PHY_INTERFACE_MODE_10GBASER: -+ pcw = 0x33900000; -+ tdc_pcw = 0x67200000; -+ break; -+ default: -+ return; -+ } -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3, -+ AIROHA_PCS_PMA_LCPLL_NCPO_LOAD); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW, -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW, pcw)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_PCW_1, -+ AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON, -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_GPON, -+ tdc_pcw)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_PCW_2, -+ AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON, -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PON_HRDDS_PCW_NCPO_EPON, -+ tdc_pcw)); -+} -+ -+static void an7583_pcs_common_phya_tx(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 fir_cn1, fir_c0b, fir_c1, fir_c2; -+ u32 tx_ben_exten_ftune; -+ u32 tx_dly_data_ftune; -+ u32 tx_dly_ben_ftune; -+ u32 ckin_divisor; -+ u32 tx_rate_ctrl; -+ -+ if (data->port_type == AIROHA_PCS_ETH || -+ data->port_type == AIROHA_PCS_PON || -+ data->port_type == AIROHA_PCS_PCIE) -+ tx_ben_exten_ftune = 0x2; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ ckin_divisor = BIT(1); -+ tx_rate_ctrl = BIT(0); -+ fir_cn1 = 0; -+ fir_c0b = 8; -+ fir_c1 = 0; -+ fir_c2 = 0; -+ -+ if (data->port_type == AIROHA_PCS_PON) { -+ tx_ben_exten_ftune = 0x7; -+ tx_dly_ben_ftune = 0x2; -+ tx_dly_data_ftune = 0x6; -+ } -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ ckin_divisor = BIT(2); -+ tx_rate_ctrl = BIT(0); -+ fir_cn1 = 0; -+ fir_c0b = 8; -+ fir_c1 = 1; -+ fir_c2 = 0; -+ if (data->port_type == AIROHA_PCS_PON) -+ tx_ben_exten_ftune = 0x2; -+ break; -+ case PHY_INTERFACE_MODE_5GBASER: -+ ckin_divisor = BIT(2); -+ tx_rate_ctrl = BIT(1); -+ fir_cn1 = 0; -+ fir_c0b = 14; -+ fir_c1 = 4; -+ fir_c2 = 0; -+ if (data->port_type == AIROHA_PCS_PON) -+ tx_ben_exten_ftune = 0x2; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ ckin_divisor = BIT(2) | BIT(0); -+ tx_rate_ctrl = BIT(1); -+ fir_cn1 = 0; -+ fir_c0b = 14; -+ fir_c1 = 4; -+ fir_c2 = 0; -+ -+ if (data->port_type == AIROHA_PCS_PON) { -+ tx_ben_exten_ftune = 0x16; -+ tx_dly_ben_ftune = 0xd; -+ tx_dly_data_ftune = 0x30; -+ } -+ -+ break; -+ default: -+ return; -+ } -+ -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TX_CKLDO_EN, -+ AIROHA_PCS_ANA_TX_DMEDGEGEN_EN | -+ AIROHA_PCS_ANA_TX_CKLDO_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CMN_EN, -+ AIROHA_PCS_ANA_CMN_VREFSEL | -+ AIROHA_PCS_ANA_CMN_MPXSELTOP_DC | -+ AIROHA_PCS_ANA_CMN_EN, -+ AIROHA_PCS_ANA_CMN_VREFSEL_9V | -+ FIELD_PREP(AIROHA_PCS_ANA_CMN_MPXSELTOP_DC, 0x1) | -+ AIROHA_PCS_ANA_CMN_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_ACJTAG_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_SEL | -+ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_SEL); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C0B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1 | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_CN1 | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_CN1, fir_cn1) | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C0B | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C0B, fir_c0b)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_FIR_C1, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2 | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | -+ AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C2 | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C2, fir_c2) | -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_FIR_C1 | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_FIR_C1, fir_c1)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_TERM_SEL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | -+ AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_CKIN_DIVISOR | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_CKIN_DIVISOR, -+ ckin_divisor)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | -+ AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TX_RATE_CTRL | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_TX_RATE_CTRL, -+ tx_rate_ctrl)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_XPON_TX_RATE_CTRL, -+ AIROHA_PCS_PMA_PON_TX_RATE_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_PON_TX_RATE_CTRL, -+ tx_rate_ctrl)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_TX_DLY_CTRL, -+ AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE, -+ FIELD_PREP(AIROHA_PCS_PMA_TX_BEN_EXTEN_FTUNE, tx_ben_exten_ftune)); -+ -+ if (data->port_type == AIROHA_PCS_PON) { -+ if (interface == PHY_INTERFACE_MODE_SGMII || interface == PHY_INTERFACE_MODE_1000BASEX || -+ interface == PHY_INTERFACE_MODE_USXGMII || interface == PHY_INTERFACE_MODE_10GBASER) -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_TX_DLY_CTRL, -+ AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE | -+ AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE, -+ FIELD_PREP(AIROHA_PCS_PMA_TX_DLY_BEN_FTUNE, tx_dly_ben_ftune) | -+ FIELD_PREP(AIROHA_PCS_PMA_TX_DLY_DATA_FTUNE, tx_dly_data_ftune)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_MD32_MEM_CLK_CTRL, -+ AIROHA_PCS_PMA_MD32PM_CK_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_MD32PM_CK_SEL, 0x3)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_TX_DLY_CTRL, -+ AIROHA_PCS_PMA_OUTBEN_DATA_MODE, -+ FIELD_PREP(AIROHA_PCS_PMA_OUTBEN_DATA_MODE, 0x1)); -+ } -+} -+ -+static void an7583_pcs_common_phya_rx(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 cdr_pr_beta_dac; -+ u32 rx_force_mode_0; -+ u32 dig_reserve_0; -+ u32 rx_rate_ctrl; -+ u32 fe_gain_ctrl; -+ u32 busbit_sel; -+ u32 phyck_sel; -+ u32 phyck_div; -+ u32 lpf_ratio; -+ u32 rx_rev0; -+ u32 osr; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ dig_reserve_0 = 0x300; -+ cdr_pr_beta_dac = 0x8; -+ phyck_sel = 0x1; -+ phyck_div = 0x29; -+ lpf_ratio = 0x3; -+ osr = 0x3; -+ rx_rate_ctrl = 0x0; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ dig_reserve_0 = 0x300; -+ cdr_pr_beta_dac = 0x6; -+ phyck_sel = 0x1; -+ phyck_div = 0xb; -+ lpf_ratio = 0x1; -+ osr = 0x1; -+ rx_rate_ctrl = 0x0; -+ break; -+ case PHY_INTERFACE_MODE_5GBASER: -+ dig_reserve_0 = 0x400; -+ cdr_pr_beta_dac = 0x8; -+ phyck_sel = 0x2; -+ phyck_div = 0x42; -+ lpf_ratio = 0x1; -+ osr = 0x1; -+ rx_rate_ctrl = 0x2; -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ dig_reserve_0 = 0x100; -+ cdr_pr_beta_dac = 0x8; -+ phyck_sel = 0x2; -+ phyck_div = 0x42; -+ lpf_ratio = 0x0; -+ osr = 0x0; -+ rx_rate_ctrl = 0x2; -+ break; -+ default: -+ return; -+ } -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_REV_0, -+ AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL | -+ AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL | -+ AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, -+ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF1_BIAS_CTRL, BIT(2)) | -+ FIELD_PREP(AIROHA_PCS_ANA_REV_1_FE_BUF2_BIAS_CTRL, BIT(2)) | -+ FIELD_PREP(AIROHA_PCS_ANA_REV_1_SIGDET_ILEAK, 0x0)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_OSCAL_WATCH_WNDW, -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE, -+ FIELD_PREP(AIROHA_PCS_ANA_RX_OSCAL_FORCE, -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA2IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_VGA1IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE2IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1VOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_CTLE1IOS | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_LVSH | -+ AIROHA_PCS_ANA_RX_OSCAL_FORCE_COMPOS)); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PD_PICAL_CKD8_INV, -+ AIROHA_PCS_ANA_CDR_PD_EDGE_DIS | -+ AIROHA_PCS_ANA_CDR_PD_PICAL_CKD8_INV); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_AEQ_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_INJCK_SEL | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_INJCK_SEL); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_12, -+ AIROHA_PCS_PMA_RESERVE_12_FEOS_0); -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII || -+ interface == PHY_INTERFACE_MODE_10GBASER) { -+ rx_rev0 = FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE, 0x1) | -+ FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL, 0x3); -+ fe_gain_ctrl = 0x1; -+ rx_force_mode_0 = 0x1; -+ } else { -+ rx_rev0 = FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF2_BIAS_TYPE, 0x1) | -+ AIROHA_PCS_ANA_REV_0_OSCAL_FE_MODE_SET_SEL | -+ BIT(7) | /* FIXME: Missing documentation for this BIT */ -+ FIELD_PREP(AIROHA_PCS_ANA_REV_0_FE_BUF_GAIN_MODE_NORMAL, 0x3); -+ fe_gain_ctrl = 0x3; -+ rx_force_mode_0 = 0x3; -+ } -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_REV_0, -+ AIROHA_PCS_ANA_RX_REV_0, rx_rev0); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, -+ fe_gain_ctrl)); -+ -+ regmap_write(pcs_pma, AIROHA_PCS_PMA_DIG_RESERVE_0, -+ dig_reserve_0); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0, -+ AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_XPON_RX_FE_GAIN_CTRL, -+ rx_force_mode_0)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_0, -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_GAIN_CTRL); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_BETA_DAC, -+ AIROHA_PCS_ANA_CDR_PR_BETA_DAC, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_BETA_DAC, -+ cdr_pr_beta_dac)); -+ -+ if (data->port_type == AIROHA_PCS_ETH && -+ interface == PHY_INTERFACE_MODE_2500BASEX) -+ regmap_update_bits(priv->pcs_ana, -+ AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, -+ AIROHA_PCS_ANA_CDR_PR_DAC_BAND, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_DAC_BAND, -+ 0x6)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, -+ AIROHA_PCS_ANA_RX_PHYCK_SEL, -+ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_SEL, phyck_sel)); -+ -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, -+ AIROHA_PCS_ANA_CDR_PR_XFICK_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, -+ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE | -+ AIROHA_PCS_ANA_RX_PHY_CK_SEL, -+ AIROHA_PCS_ANA_RX_PHY_CK_SEL_FORCE); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, -+ AIROHA_PCS_ANA_RX_PHYCK_RSTB | -+ AIROHA_PCS_ANA_RX_PHYCK_DIV, -+ AIROHA_PCS_ANA_RX_PHYCK_RSTB | -+ FIELD_PREP(AIROHA_PCS_ANA_RX_PHYCK_DIV, phyck_div)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, -+ AIROHA_PCS_ANA_CDR_LPF_RATIO, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO, -+ lpf_ratio)); -+ -+ if (interface == PHY_INTERFACE_MODE_5GBASER) -+ busbit_sel = AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE | -+ AIROHA_PCS_ANA_RX_BUSBIT_SEL_16BIT; -+ else -+ busbit_sel = 0; -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_BUSBIT_SEL, -+ AIROHA_PCS_ANA_RX_BUSBIT_SEL_FORCE | -+ AIROHA_PCS_ANA_RX_BUSBIT_SEL, -+ busbit_sel); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_AEQ_SPEED, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | -+ AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_OSR_SEL | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_OSR_SEL, osr)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_XPON_RX_RESERVED_1, -+ AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_XPON_RX_RATE_CTRL, rx_rate_ctrl)); -+} -+ -+static void an7583_pcs_common_phya_ana(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 lpf_br, lpf_bwr; -+ u32 txpll_chp_ibias; -+ bool chp_double_en; -+ u32 tcl_amp_vref; -+ bool sdm_hren; -+ bool sdm_ifm; -+ u32 vco_cfix; -+ bool sdm_di; -+ bool vcodiv; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ if (data->port_type == AIROHA_PCS_PON) { -+ txpll_chp_ibias = 0x18; -+ lpf_br = 0xa; -+ lpf_bwr = 0x16; -+ } else { -+ txpll_chp_ibias = 0x31; -+ lpf_br = 0x5; -+ lpf_bwr = 0xb; -+ } -+ vco_cfix = 0x3; -+ tcl_amp_vref = 0xb; -+ vcodiv = false; -+ sdm_hren = data->port_type == AIROHA_PCS_PON; -+ sdm_ifm = data->port_type == AIROHA_PCS_PON; -+ sdm_di = data->port_type == AIROHA_PCS_PON; -+ chp_double_en = false; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ txpll_chp_ibias = 0x1e; -+ if (data->port_type == AIROHA_PCS_PCIE) { -+ lpf_br = 0xa; -+ lpf_bwr = 0x16; -+ } else { -+ lpf_br = 0x5; -+ lpf_bwr = 0xb; -+ } -+ vco_cfix = 0x0; -+ tcl_amp_vref = 0xe; -+ vcodiv = true; -+ sdm_hren = false; -+ sdm_ifm = false; -+ sdm_di = false; -+ chp_double_en = data->port_type == AIROHA_PCS_PON || -+ data->port_type == AIROHA_PCS_PCIE; -+ break; -+ case PHY_INTERFACE_MODE_5GBASER: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_USXGMII: -+ txpll_chp_ibias = 0x18; -+ lpf_br = 0xa; -+ lpf_bwr = 0x16; -+ sdm_hren = true; -+ vco_cfix = 0x2; -+ tcl_amp_vref = 0xb; -+ vcodiv = false; -+ sdm_ifm = true; -+ sdm_di = true; -+ chp_double_en = false; -+ break; -+ default: -+ return; -+ } -+ -+ if (data->port_type == AIROHA_PCS_PON || -+ data->port_type == AIROHA_PCS_PCIE) -+ /* XPON TDC */ -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_PLL_MONCLK_SEL, -+ AIROHA_PCS_ANA_TDC_AUTOEN); -+ -+ /* TXPLL VCO LDO Out */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, -+ AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT | -+ AIROHA_PCS_ANA_TXPLL_LDO_OUT, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_VCO_OUT, 0x1) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LDO_OUT, 0x1)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_VTP_EN, -+ AIROHA_PCS_ANA_TXPLL_VTP | -+ AIROHA_PCS_ANA_TXPLL_VTP_EN, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VTP, 0x0) | -+ AIROHA_PCS_ANA_TXPLL_VTP_EN); -+ -+ if (data->port_type == AIROHA_PCS_ETH || -+ data->port_type == AIROHA_PCS_PON) -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TDC_SYNC_CK_SEL, -+ AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL | -+ AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN, -+ FIELD_PREP(AIROHA_PCS_ANA_PLL_LDO_CKDRV_VSEL, 0x1) | -+ AIROHA_PCS_ANA_PLL_LDO_CKDRV_EN); -+ -+ /* Setup RSTB */ -+ /* FIXME: different order */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_REFIN_INTERNAL, -+ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | -+ AIROHA_PCS_ANA_TXPLL_RST_DLY | -+ AIROHA_PCS_ANA_TXPLL_REFIN_DIV | -+ AIROHA_PCS_ANA_TXPLL_REFIN_INTERNAL, -+ AIROHA_PCS_ANA_TXPLL_PLL_RSTB | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_RST_DLY, 0x4) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_REFIN_DIV, -+ AIROHA_PCS_ANA_TXPLL_REFIN_DIV_1)); -+ -+ /* Setup SDM */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_DI_EN, -+ AIROHA_PCS_ANA_TXPLL_SDM_MODE | -+ AIROHA_PCS_ANA_TXPLL_SDM_IFM | -+ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS | -+ AIROHA_PCS_ANA_TXPLL_SDM_DI_EN, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_MODE, 0) | -+ (sdm_ifm ? AIROHA_PCS_ANA_TXPLL_SDM_IFM : 0) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_DI_LS, -+ AIROHA_PCS_ANA_TXPLL_SDM_DI_LS_2_23) | -+ (sdm_di ? AIROHA_PCS_ANA_TXPLL_SDM_DI_EN : 0)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, -+ AIROHA_PCS_ANA_TXPLL_SDM_HREN | -+ AIROHA_PCS_ANA_TXPLL_SDM_OUT | -+ AIROHA_PCS_ANA_TXPLL_SDM_ORD, -+ (sdm_hren ? AIROHA_PCS_ANA_TXPLL_SDM_HREN : 0) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SDM_ORD, -+ AIROHA_PCS_ANA_TXPLL_SDM_ORD_3SDM)); -+ -+ /* Setup SSC */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_DELTA1, -+ AIROHA_PCS_ANA_TXPLL_SSC_DELTA | -+ AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA, 0x0) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_DELTA1, 0x0)); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_EN, -+ AIROHA_PCS_ANA_TXPLL_SSC_TRI_EN | -+ AIROHA_PCS_ANA_TXPLL_SSC_PHASE_INI | -+ AIROHA_PCS_ANA_TXPLL_SSC_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_SSC_PERIOD, -+ AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_SSC_PERIOD, 0x0)); -+ -+ regmap_update_bits(priv->pcs_ana, AN7583_PCS_ANA_PXP_TXPLL_CHP_DOUBLE_EN, -+ AIROHA_PCS_ANA_TXPLL_SPARE_L, -+ chp_double_en ? AIROHA_PCS_ANA_TXPLL_SPARE_L : 0); -+ -+ /* Setup LPF */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_CHP_IBIAS, -+ AIROHA_PCS_ANA_TXPLL_LPF_BC | -+ AIROHA_PCS_ANA_TXPLL_LPF_BR | -+ AIROHA_PCS_ANA_TXPLL_CHP_IOFST | -+ AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BC, 0x1f) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BR, lpf_br) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IOFST, 0x0) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_CHP_IBIAS, txpll_chp_ibias)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, -+ AIROHA_PCS_ANA_TXPLL_LPF_BWC | -+ AIROHA_PCS_ANA_TXPLL_LPF_BWR | -+ AIROHA_PCS_ANA_TXPLL_LPF_BP, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWC, 0x18) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BWR, lpf_bwr) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_LPF_BP, 0x2)); -+ -+ /* Setup VCO */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, -+ AIROHA_PCS_ANA_TXPLL_VCO_CFIX, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_CFIX, vco_cfix)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_VCO_HALFLSB_EN, -+ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L | -+ AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H | -+ AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR | -+ AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR | -+ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_L, 0x0) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_VCOVAR_BIAS_H, 0x4) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_TCLVAR, 0x4) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCO_SCAPWR, 0x7) | -+ AIROHA_PCS_ANA_TXPLL_VCO_HALFLSB_EN); -+ -+ /* Setup KBand */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_CODE, -+ AIROHA_PCS_ANA_TXPLL_KBAND_KF | -+ AIROHA_PCS_ANA_TXPLL_KBAND_KFC | -+ AIROHA_PCS_ANA_TXPLL_KBAND_DIV | -+ AIROHA_PCS_ANA_TXPLL_KBAND_CODE, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KF, 0x3) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KFC, 0x0) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_DIV, 0x2) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_CODE, 0xe4)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, -+ AIROHA_PCS_ANA_TXPLL_KBAND_KS, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_KBAND_KS, 0x1)); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_LPF_BP, -+ AIROHA_PCS_ANA_TXPLL_KBAND_OPTION); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, -+ AIROHA_PCS_ANA_TXPLL_VCO_KBAND_MEAS_EN); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_KBAND_LOAD_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN | -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_KBAND_LOAD_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_KBAND_LOAD_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_KBAND_KS, -+ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE | -+ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE, -+ AIROHA_PCS_ANA_TXPLL_MMD_PREDIV_MODE_2) | -+ AIROHA_PCS_ANA_TXPLL_POSTDIV_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_AMP_GAIN, -+ AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF | -+ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_AMP_VREF, tcl_amp_vref) | -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN, -+ AIROHA_PCS_ANA_TXPLL_TCL_AMP_GAIN_4)); -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, -+ AIROHA_PCS_ANA_TXPLL_POSTDIV_D256_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, -+ AIROHA_PCS_ANA_TXPLL_VCODIV, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_VCODIV, -+ vcodiv ? AIROHA_PCS_ANA_TXPLL_VCODIV_2 : -+ AIROHA_PCS_ANA_TXPLL_VCODIV_1)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, -+ AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_KBAND_VREF, 0xf)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_LPF_EN, -+ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW | -+ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN, -+ FIELD_PREP(AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW, -+ AIROHA_PCS_ANA_TXPLL_TCL_LPF_BW_0_5) | -+ AIROHA_PCS_ANA_TXPLL_TCL_LPF_EN); -+ -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_SDM_ORD, -+ AIROHA_PCS_ANA_TXPLL_TCL_AMP_EN); -+ -+ /* Setup TX TermCal */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TX_TXLBRC_EN, -+ AIROHA_PCS_ANA_TX_TERMCAL_VREF_L | -+ AIROHA_PCS_ANA_TX_TERMCAL_VREF_H, -+ FIELD_PREP(AIROHA_PCS_ANA_TX_TERMCAL_VREF_L, 0x2) | -+ FIELD_PREP(AIROHA_PCS_ANA_TX_TERMCAL_VREF_H, 0x2)); -+ -+ /* Setup XPON RX */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_FE_EQ_HZEN, -+ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | -+ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | -+ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN | -+ AIROHA_PCS_ANA_RX_FE_EQ_HZEN, -+ AIROHA_PCS_ANA_RX_FE_VB_EQ3_EN | -+ AIROHA_PCS_ANA_RX_FE_VB_EQ2_EN | -+ AIROHA_PCS_ANA_RX_FE_VB_EQ1_EN); -+ -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_FE_VCM_GEN_PWDB, -+ AIROHA_PCS_ANA_RX_FE_VCM_GEN_PWDB); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, -+ AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_TOP_LIM, 0x8000)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_BOT_LIM, -+ AIROHA_PCS_ANA_CDR_LPF_BOT_LIM, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_BOT_LIM, 0x78000)); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV, -+ AIROHA_PCS_ANA_CDR_PR_RSTB_BYPASS); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, -+ AIROHA_PCS_ANA_RX_DAC_RANGE_EYE, -+ FIELD_PREP(AIROHA_PCS_ANA_RX_DAC_RANGE_EYE, 0x2)); -+} -+ -+static void an7583_pcs_cfg_phy_type(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ /* Enable PLL force selection and Force Disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN); -+ -+ if (data->port_type == AIROHA_PCS_PON || -+ data->port_type == AIROHA_PCS_PCIE) { -+ /* TDC */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3, -+ AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT, -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_NCPO_SHIFT, 0x1)); -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_1, -+ AIROHA_PCS_PMA_LCPLL_A_TDC, -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_A_TDC, 0x5)); -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TX_TERMCAL_SELPN, -+ AIROHA_PCS_ANA_TX_TDC_CK_SEL, -+ FIELD_PREP(AIROHA_PCS_ANA_TX_TDC_CK_SEL, 0x0)); -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_PHYCK_DIV, -+ AIROHA_PCS_ANA_RX_TDC_CK_SEL); -+ } -+ -+ /* PLL EN HW Mode */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_1, -+ AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER | -+ AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER | -+ AIROHA_PCS_PMA_LCPLL_EN_TIMER | -+ AIROHA_PCS_PMA_LCPLL_MAN_PWDB, -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_CK_STB_TIMER, 0x1) | -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_PCW_MAN_LOAD_TIMER, 0x10) | -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_EN_TIMER, 0xa) | -+ AIROHA_PCS_PMA_LCPLL_MAN_PWDB); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_1, -+ AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT | -+ AIROHA_PCS_PMA_TX_CK_EN_WAIT, -+ FIELD_PREP(AIROHA_PCS_PMA_TX_HSDATA_EN_WAIT, 0x113) | -+ FIELD_PREP(AIROHA_PCS_PMA_TX_CK_EN_WAIT, 0xfa)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_2, -+ AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT | -+ AIROHA_PCS_PMA_TX_POWER_ON_WAIT, -+ FIELD_PREP(AIROHA_PCS_PMA_TX_SERDES_RDY_WAIT, 0x9b) | -+ FIELD_PREP(AIROHA_PCS_PMA_TX_POWER_ON_WAIT, 0x210)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PON_TX_COUNTER_0, -+ AIROHA_PCS_PMA_TXCALIB_5US | -+ AIROHA_PCS_PMA_TXCALIB_50US, -+ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_5US, 0x4) | -+ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_50US, 0x26)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_0, -+ AIROHA_PCS_PMA_LCPLL_KI, -+ FIELD_PREP(AIROHA_PCS_PMA_LCPLL_KI, 0x3)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_PW_5, -+ AIROHA_PCS_PMA_LCPLL_TDC_SYNC_IN_MODE); -+ -+ an7583_pcs_common_phya_txpll(priv, index, interface); -+ an7583_pcs_common_phya_tx(priv, index, interface); -+ -+ /* RX HW mode counter */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0, -+ AIROHA_PCS_PMA_RX_OS_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_START, 0x1)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_6, -+ AIROHA_PCS_PMA_RX_OS_END, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_OS_END, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_0, -+ AIROHA_PCS_PMA_OSC_SPEED_OPT, -+ AIROHA_PCS_PMA_OSC_SPEED_OPT_0_1); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_1, -+ AIROHA_PCS_PMA_RX_PICAL_END | -+ AIROHA_PCS_PMA_RX_PICAL_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_END, 0x3e8) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PICAL_START, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_4, -+ AIROHA_PCS_PMA_RX_SDCAL_END | -+ AIROHA_PCS_PMA_RX_SDCAL_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_END, 0x3e8) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_SDCAL_START, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_2, -+ AIROHA_PCS_PMA_RX_PDOS_END | -+ AIROHA_PCS_PMA_RX_PDOS_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_END, 0x3e8) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_PDOS_START, 0x2)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_3, -+ AIROHA_PCS_PMA_RX_FEOS_END | -+ AIROHA_PCS_PMA_RX_FEOS_START, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_END, 0x3e8) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_FEOS_START, 0x2)); -+ -+ /* RX Settings */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2, -+ AIROHA_PCS_PMA_FOM_NUM_ORDER | -+ AIROHA_PCS_PMA_A_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_FOM_NUM_ORDER, 0x1) | -+ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x3)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0, -+ AIROHA_PCS_PMA_X_MAX | AIROHA_PCS_PMA_X_MIN, -+ FIELD_PREP(AIROHA_PCS_PMA_X_MAX, 0x240) | -+ FIELD_PREP(AIROHA_PCS_PMA_X_MIN, 0x1c0)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, -+ AIROHA_PCS_PMA_DATA_SHIFT); -+ -+ an7583_pcs_common_phya_rx(priv, index, interface); -+ an7583_pcs_common_phya_ana(priv, index, interface); -+ -+ /* Setup EYE */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, -+ AIROHA_PCS_PMA_EYECNT_FAST); -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3, -+ AIROHA_PCS_PMA_EYE_NEXTPTS); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0, -+ AIROHA_PCS_PMA_EYECNT_VTH | -+ AIROHA_PCS_PMA_EYECNT_HTH, -+ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_VTH, 0x4) | -+ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_HTH, 0x4)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1, -+ AIROHA_PCS_PMA_EO_VTH | -+ AIROHA_PCS_PMA_EO_HTH, -+ FIELD_PREP(AIROHA_PCS_PMA_EO_VTH, 0x4) | -+ FIELD_PREP(AIROHA_PCS_PMA_EO_HTH, 0x4)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, -+ AIROHA_PCS_PMA_EYE_MASK | -+ AIROHA_PCS_PMA_CNTLEN, -+ FIELD_PREP(AIROHA_PCS_PMA_EYE_MASK, 0xff) | -+ FIELD_PREP(AIROHA_PCS_PMA_CNTLEN, 0xd0)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, -+ AIROHA_PCS_PMA_VEO_MASK | -+ AIROHA_PCS_PMA_HEO_MASK | -+ AIROHA_PCS_PMA_EQ_EN_DELAY, -+ FIELD_PREP(AIROHA_PCS_PMA_VEO_MASK, 0x0) | -+ FIELD_PREP(AIROHA_PCS_PMA_HEO_MASK, 0x0) | -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x1)); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_1, -+ AIROHA_PCS_PMA_A_LGAIN); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CAL1, -+ AIROHA_PCS_PMA_CAL_CYC | -+ AIROHA_PCS_PMA_CAL_STB | -+ AIROHA_PCS_PMA_CAL_1US_SET | -+ AIROHA_PCS_PMA_SIM_FAST_EN, -+ AIROHA_PCS_PMA_CAL_CYC_15 | -+ AIROHA_PCS_PMA_CAL_STB_8US | -+ FIELD_PREP(AIROHA_PCS_PMA_CAL_1US_SET, 0x2e) | -+ AIROHA_PCS_PMA_SIM_FAST_EN); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CAL2, -+ AIROHA_PCS_PMA_CAL_CYC_TIME | -+ AIROHA_PCS_PMA_CAL_OUT_OS | -+ AIROHA_PCS_PMA_CAL_OS_PULSE, -+ FIELD_PREP(AIROHA_PCS_PMA_CAL_CYC_TIME, 0x0) | -+ FIELD_PREP(AIROHA_PCS_PMA_CAL_OUT_OS, 0x0)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_CTRL_5, -+ AIROHA_PCS_PMA_RX_RDY | -+ AIROHA_PCS_PMA_RX_BLWC_RDY_EN, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_RDY, 0xa) | -+ FIELD_PREP(AIROHA_PCS_PMA_RX_BLWC_RDY_EN, 0x5)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FEOS, -+ AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE | -+ AIROHA_PCS_PMA_LFSEL, -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_FORCE_BLWC_FREEZE, 0x0)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1, -+ AIROHA_PCS_PMA_INDEX_MODE | -+ AIROHA_PCS_PMA_Y_MAX | -+ AIROHA_PCS_PMA_Y_MIN, -+ AIROHA_PCS_PMA_INDEX_MODE | -+ FIELD_PREP(AIROHA_PCS_PMA_Y_MAX, 0x3f) | -+ FIELD_PREP(AIROHA_PCS_PMA_Y_MIN, 0x40)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2, -+ AIROHA_PCS_PMA_EYEDUR, -+ FIELD_PREP(AIROHA_PCS_PMA_EYEDUR, 0x18)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EXTRAL_CTRL, -+ AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME | -+ AIROHA_PCS_PMA_OS_RDY_LATCH | -+ AIROHA_PCS_PMA_DISB_LEQ, -+ FIELD_PREP(AIROHA_PCS_PMA_L2D_TRIG_EQ_EN_TIME, 0x2) | -+ AIROHA_PCS_PMA_OS_RDY_LATCH); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_0, -+ AIROHA_PCS_PMA_KBAND_KFC | -+ AIROHA_PCS_PMA_FPKDIV, -+ AIROHA_PCS_PMA_KBAND_KFC_8 | -+ FIELD_PREP(AIROHA_PCS_PMA_FPKDIV, 0xa5)); -+ -+ if (data->port_type == AIROHA_PCS_PCIE) -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_0, -+ AIROHA_PCS_PMA_KBAND_PREDIV, -+ AIROHA_PCS_PMA_KBAND_PREDIV_8); -+ else -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_0, -+ AIROHA_PCS_PMA_KBAND_PREDIV, -+ AIROHA_PCS_PMA_KBAND_PREDIV_4); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_1, -+ AIROHA_PCS_PMA_SYMBOL_WD | -+ AIROHA_PCS_PMA_SETTLE_TIME_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_SYMBOL_WD, 0x4) | -+ FIELD_PREP(AIROHA_PCS_PMA_SETTLE_TIME_SEL, 0x1)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_5, -+ AIROHA_PCS_PMA_FLL_IDAC_MIN | -+ AIROHA_PCS_PMA_FLL_IDAC_MAX, -+ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MIN, 0x400) | -+ FIELD_PREP(AIROHA_PCS_PMA_FLL_IDAC_MAX, 0x1ff)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_2, -+ AIROHA_PCS_PMA_AMP | -+ AIROHA_PCS_PMA_PRBS_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_AMP, 0x4) | -+ FIELD_PREP(AIROHA_PCS_PMA_PRBS_SEL, 0x3)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_4, -+ AIROHA_PCS_PMA_DISB_BLWC_OFFSET); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_PDOS_CTRL_0, -+ AIROHA_PCS_PMA_EYE_BLWC_ADD | -+ AIROHA_PCS_PMA_DATA_BLWC_ADD, -+ AIROHA_PCS_PMA_DATA_BLWC_ADD); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_BLWC, -+ AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM | -+ AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM | -+ AIROHA_PCS_PMA_EQ_BLWC_GAIN | -+ AIROHA_PCS_PMA_EQ_BLWC_POL, -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_CNT_BOT_LIM, 0x10) | -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_CNT_TOP_LIM, 0x70) | -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_BLWC_GAIN, 0xa) | -+ AIROHA_PCS_PMA_EQ_BLWC_POL_INVERSION); -+} -+ -+static void an7583_pcs_common_phya_txpll_on(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ if (data->port_type == AIROHA_PCS_PCIE) { -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_JCPLL_SPARE_H, -+ AIROHA_PCS_ANA_JCPLL_SPARE_L, -+ FIELD_PREP(AIROHA_PCS_ANA_JCPLL_SPARE_L, -+ AIROHA_PCS_ANA_JCPLL_SPARE_L_LDO)); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_JCPLL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_JCPLL_EN); -+ } -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_LCPLL_PWCTL_SETTING_0, -+ AIROHA_PCS_PMA_SW_LCPLL_EN); -+ -+ udelay(6); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_CKOUT_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_CKOUT_EN | -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_CKOUT_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, -+ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN | -+ AIROHA_PCS_ANA_TXPLL_VREF_SEL, -+ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN | -+ AIROHA_PCS_ANA_TXPLL_VREF_SEL_VBG); -+ -+ regmap_set_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_PHY_CK1_EN, -+ AIROHA_PCS_ANA_TXPLL_PHY_CK2_EN | -+ AIROHA_PCS_ANA_TXPLL_PHY_CK1_EN); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_TXPLL_TCL_KBAND_VREF, -+ AIROHA_PCS_ANA_TXPLL_FREQ_MEAS_EN); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_JCPLL_FREQ_MEAS_EN, -+ AIROHA_PCS_ANA_TXPLL_IB_EXT_EN); -+ -+ if (data->port_type == AIROHA_PCS_PCIE) -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FREQ_DET_1, -+ AIROHA_PCS_PMA_UNLOCK_CYCLECNT | -+ AIROHA_PCS_PMA_LOCK_CYCLECNT, -+ FIELD_PREP(AIROHA_PCS_PMA_UNLOCK_CYCLECNT, 0x7fff) | -+ FIELD_PREP(AIROHA_PCS_PMA_LOCK_CYCLECNT, 0x7fff)); -+ -+ usleep_range(500, 1000); -+} -+ -+static void an7583_pcs_common_phya_tx_on(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 xfi_tx_term_sel = 0x1; -+ // int efuse_valid; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_TX_RST_B, -+ AIROHA_PCS_PMA_TX_TOP_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_ADD_CLKPATH_RST_0, -+ AIROHA_PCS_PMA_CLKPATH_RSTB_CK | -+ AIROHA_PCS_PMA_CLKPATH_RST_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_TX_RST_B, -+ AIROHA_PCS_PMA_TXCALIB_RST_B | -+ AIROHA_PCS_PMA_TX_TOP_RST_B); -+ -+ usleep_range(100, 200); -+ -+ /* TODO handle efuse */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_TX_CALIB_0, -+ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL | -+ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN, -+ FIELD_PREP(AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL, -+ xfi_tx_term_sel) | -+ AIROHA_PCS_PMA_TXCALIB_FORCE_TERMP_SEL_EN); -+} -+ -+static void an7583_pcs_common_phya_rx_preset(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 cdr_pr_buf_in_sr; -+ bool cdr_pr_cap_en; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_2500BASEX: -+ if (data->port_type == AIROHA_PCS_PCIE) { -+ cdr_pr_cap_en = false; -+ cdr_pr_buf_in_sr = 0x7; -+ } else { -+ cdr_pr_cap_en = true; -+ cdr_pr_buf_in_sr = 0x6; -+ } -+ -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_5GBASER: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_USXGMII: -+ cdr_pr_cap_en = false; -+ cdr_pr_buf_in_sr = 0x7; -+ break; -+ default: -+ return; -+ } -+ -+ /* Setup RX Precondition */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, -+ AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL | -+ AIROHA_PCS_ANA_RX_SIGDET_PEAK, -+ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_VTH_SEL, 0x2) | -+ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_PEAK, 0x2)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_DAC_RANGE, -+ AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, -+ FIELD_PREP(AIROHA_PCS_ANA_RX_SIGDET_LPF_CTRL, 0x3)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_MONPR_EN, -+ AIROHA_PCS_ANA_CDR_PR_CAP_EN | -+ AIROHA_PCS_ANA_CDR_BUF_IN_SR, -+ (cdr_pr_cap_en ? AIROHA_PCS_ANA_CDR_PR_CAP_EN : 0) | -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_BUF_IN_SR, cdr_pr_buf_in_sr)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_OS_RDY); -+ -+ /* Setup L2R */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); -+ -+ /* Setup LEQ setting */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, 0x0)); -+ -+ /* Keep EYE reset */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, -+ AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, -+ AIROHA_PCS_PMA_DISB_EYE_TOP_EN); -+ -+ /* Kepp BLWC reset */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_BLWC_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_BLWC_EN); -+} -+ -+static void an7583_pcs_common_phya_rx_on(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_KBAND_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_KBAND_RSTB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PD_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PD_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PD_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PWDB); -+ -+ /* RX SigDet Pwdb */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_PWDB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_SCAN_RST_B, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SCAN_RST_B | -+ AIROHA_PCS_PMA_FORCE_DA_RX_SCAN_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_0, -+ AIROHA_PCS_PMA_XPON_CDR_PD_PWDB | -+ AIROHA_PCS_PMA_XPON_CDR_PR_PIEYE_PWDB | -+ AIROHA_PCS_PMA_XPON_CDR_PW_PWDB | -+ AIROHA_PCS_PMA_XPON_RX_FE_PWDB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SS_DA_XPON_PWDB_1, -+ AIROHA_PCS_PMA_RX_SIDGET_PWDB); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_SYS_EN_SEL_0, -+ AIROHA_PCS_PMA_RX_SYS_EN_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_RX_SYS_EN_SEL, 0x1)); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, -+ AIROHA_PCS_ANA_CDR_PR_FBKSEL | -+ AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL | -+ AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_FBKSEL, 0x0) | -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_CKBUF_VAL, 0x5) | -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_VREG_IBAND_VAL, 0x5)); -+ -+ if (data->port_type == AIROHA_PCS_PCIE) -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_VREG_IBAND_VAL, -+ AIROHA_PCS_ANA_CDR_PR_DAC_BAND, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_PR_DAC_BAND, 0x8)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_PDOS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_FEOS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_SDCAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_OS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_BLWC_EN); -+ -+ if (data->port_type == AIROHA_PCS_PCIE) -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_PMA_PXP_AEQ_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_EN | -+ AIROHA_PCS_PMA_FORCE_DA_AEQ_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_AEQ_EN); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_CKREF_DIV, -+ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV, -+ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV_1); -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_PR_TDC_REF_SEL, -+ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1, -+ AIROHA_PCS_ANA_CDR_PR_CKREF_DIV1_1); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_RX_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_REF_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); -+ -+ usleep_range(100, 200); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); -+} -+ -+static void an7583_pcs_common_phya_l2d(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ /* Setup LPF L2D force and disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); -+ -+ usleep_range(200, 300); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); -+} -+ -+static void an7583_pcs_common_phya_tdc_off(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_IDAC, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_3, -+ AIROHA_PCS_PMA_LCPLL_NCPO_LOAD); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_TXPLL_SDM_PCW_CHG); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG, -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TXPLL_SDM_PCW_CHG, -+ AIROHA_PCS_PMA_FORCE_DA_TXPLL_SDM_PCW_CHG); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_FLT_1, -+ AIROHA_PCS_PMA_LCPLL_GPON_SEL, -+ AIROHA_PCS_PMA_LCPLL_GPON_SEL_FROM_EPON); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_LCPLL_TDC_PW_0, -+ AIROHA_PCS_PMA_LCPLL_TDC_DIG_PWDB); -+ -+ usleep_range(100, 200); -+} -+ -+static void an7583_pcs_common_phya_rx_oscal(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, -+ AIROHA_PCS_PMA_DISB_FBCK_LOCK); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_FBCK_LOCK); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON | -+ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN); -+ -+ usleep_range(200, 300); -+ -+ /* Set normal of force mode */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_OS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_OS_RDY); -+ -+ /* Disable force mode signal */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_OS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); -+ -+ /* Release reset enable */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_OS_EN); -+} -+ -+static void an7583_pcs_common_phya_pical(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ /* Pre Condition */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, -+ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_PI_CAL, -+ AIROHA_PCS_PMA_KPGAIN, -+ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x4)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, -+ AIROHA_PCS_PMA_EQ_EN_DELAY, -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x8)); -+ -+ /* Reset Block */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, -+ AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, -+ AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3, -+ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY); -+ -+ /* Enable */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, -+ AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, -+ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); -+ -+ /* Release Reset and Enable */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); -+ -+ usleep_range(200, 300); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, -+ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); -+} -+ -+static void an7583_pcs_common_phya_pdos(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN); -+ -+ /* Pre Condition */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_OS_RDY); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1, -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E0); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1, -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D1); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_1, -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_D0); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_E1); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_EYEDUR_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_DISB_EYEDUR_EN); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_PDOS_CTRL_0, -+ AIROHA_PCS_PMA_SAP_SEL, -+ AIROHA_PCS_PMA_SAP_SEL_SHIFT_8); -+ -+ /* Reset Block */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, -+ AIROHA_PCS_PMA_DISB_PDOS_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_1, -+ AIROHA_PCS_PMA_PDOS_RST_B); -+ -+ /* Disable */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_PDOS_EN); -+ -+ /* Release Reset and Enable */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_OS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_OS_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_PDOS_RX_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_1, -+ AIROHA_PCS_PMA_PDOS_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN); -+ -+ usleep_range(200, 300); -+ -+ /* Disable (again) */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_PDOS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_OS_EN); -+ -+ /* Release EYE related */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_EYEDUR_INIT_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_EYECNT_RX_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_EYEDUR_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_DISB_EYEDUR_EN); -+ -+ /* Disable PDOS */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_FE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_PDOSCAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_PDOSCAL_EN); -+} -+ -+static void an7583_pcs_common_phya_feos(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ /* Pre Condition */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_OS_RDY); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_FE_VOS); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_BLWC_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_BLWC_RX_RST_B); -+ -+ /* Setting */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_SS_RX_FEOS, -+ AIROHA_PCS_PMA_LFSEL, -+ FIELD_PREP(AIROHA_PCS_PMA_LFSEL, 0x30)); -+ -+ /* Reset */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_FEOS_RX_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_FEOS_RST_B); -+ -+ /* Disable */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_FEOS_EN); -+ -+ /* Release Reset and Enable */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_OS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_OS_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_FEOS_RX_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_FEOS_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN); -+ -+ usleep_range(1000, 1500); -+ -+ /* Disable */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_FEOS_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_OS_EN); -+} -+ -+static void an7583_pcs_common_phya_sdcal(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ /* Pre Condition */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN); -+ -+ /* Reset */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_CAL_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_SDCAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_SDCAL_REF_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN); -+ -+ /* Release Reset and Enable */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_CAL_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_8, -+ AIROHA_PCS_PMA_FORCE_SDCAL_REF_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN); -+ -+ usleep_range(200, 300); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_SDCAL_EN); -+ -+ /* SigDet Cal Disable */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_SIGDET_CAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_SIGDET_CAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_SIGDET_CAL_EN); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON | -+ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_CKON, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_CKON); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_RSTB); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_RX_OSCAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN | -+ AIROHA_PCS_PMA_FORCE_DA_RX_OSCAL_EN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_OSCAL_EN); -+} -+ -+static void an7583_pcs_common_phya_phy_status(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_OS_RDY); -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_OS_RDY); -+ udelay(1); -+} -+ -+static void an7583_pcs_common_phya_eye_setting(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 cdr_lpf_ratio; -+ u32 x_min, x_max; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ x_min = 0x0; -+ x_max = 0x400; -+ cdr_lpf_ratio = 0x3; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ x_min = 0x140; -+ x_max = 0x2c0; -+ cdr_lpf_ratio = 0x0; -+ break; -+ case PHY_INTERFACE_MODE_5GBASER: -+ x_min = 0x180; -+ x_max = 0x280; -+ cdr_lpf_ratio = 0x1; -+ break; -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_USXGMII: -+ x_min = 0x1c0; -+ x_max = 0x234; -+ cdr_lpf_ratio = 0x0; -+ break; -+ default: -+ return; -+ } -+ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_CDR_LPF_RATIO, -+ AIROHA_PCS_ANA_CDR_LPF_RATIO, -+ FIELD_PREP(AIROHA_PCS_ANA_CDR_LPF_RATIO, -+ cdr_lpf_ratio)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, -+ AIROHA_PCS_PMA_EYE_MASK, -+ FIELD_PREP(AIROHA_PCS_PMA_EYE_MASK, 0xff)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_0, -+ AIROHA_PCS_PMA_X_MAX | AIROHA_PCS_PMA_X_MIN, -+ FIELD_PREP(AIROHA_PCS_PMA_X_MAX, x_max) | -+ FIELD_PREP(AIROHA_PCS_PMA_X_MIN, x_min)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, -+ AIROHA_PCS_PMA_CNTLEN, -+ FIELD_PREP(AIROHA_PCS_PMA_CNTLEN, 0xf8)); -+ -+ regmap_clear_bits(priv->pcs_ana, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_0, -+ AIROHA_PCS_PMA_CNTFOREVER); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_2, -+ AIROHA_PCS_PMA_DATA_SHIFT); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_1, -+ AIROHA_PCS_PMA_INDEX_MODE); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_2, -+ AIROHA_PCS_PMA_EYEDUR, -+ FIELD_PREP(AIROHA_PCS_PMA_EYEDUR, 0x44c)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEINDEX_CTRL_3, -+ AIROHA_PCS_PMA_EYE_NEXTPTS | -+ AIROHA_PCS_PMA_EYE_NEXTPTS_TOGGLE | -+ AIROHA_PCS_PMA_EYE_NEXTPTS_SEL, -+ AIROHA_PCS_PMA_EYE_NEXTPTS); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_0, -+ AIROHA_PCS_PMA_EYECNT_VTH | -+ AIROHA_PCS_PMA_EYECNT_HTH, -+ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_VTH, 0x4) | -+ FIELD_PREP(AIROHA_PCS_PMA_EYECNT_HTH, 0x4)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYEOPENING_CTRL_1, -+ AIROHA_PCS_PMA_EO_VTH | -+ AIROHA_PCS_PMA_EO_HTH, -+ FIELD_PREP(AIROHA_PCS_PMA_EO_VTH, 0x4) | -+ FIELD_PREP(AIROHA_PCS_PMA_EO_HTH, 0x4)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_1, -+ AIROHA_PCS_PMA_B_ZERO_SEL | -+ AIROHA_PCS_PMA_HEO_EMPHASIS | -+ AIROHA_PCS_PMA_A_MGAIN | -+ AIROHA_PCS_PMA_A_LGAIN); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_2, -+ AIROHA_PCS_PMA_A_SEL, -+ FIELD_PREP(AIROHA_PCS_PMA_A_SEL, 0x1)); -+} -+ -+static void an7583_pcs_common_phya_eye_cal(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_TX_RATE_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE, 0x0)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_FLL_COR, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_DAC_EYE | -+ AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_DAC_EYE, 0x0)); -+ -+ /* Redo PICal and reset Block */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, -+ AIROHA_PCS_PMA_EQ_EN_DELAY, -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x80)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_PI_CAL, -+ AIROHA_PCS_PMA_KPGAIN, -+ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x1)); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, -+ AIROHA_PCS_PMA_DISB_RX_AND_PICAL_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_6, -+ AIROHA_PCS_PMA_DISB_REF_AND_PICAL_RSTB); -+ -+ /* Enable PICal */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, -+ AIROHA_PCS_PMA_DISB_RX_OR_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_0, -+ AIROHA_PCS_PMA_DISB_RX_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_0, -+ AIROHA_PCS_PMA_FORCE_RX_PICAL_EN); -+ -+ /* Release Reset */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_RESET_0, -+ AIROHA_PCS_PMA_EQ_PI_CAL_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_RX_AND_PICAL_RSTB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_7, -+ AIROHA_PCS_PMA_FORCE_REF_AND_PICAL_RSTB); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); -+ -+ usleep_range(1000, 1500); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_RX_OR_PICAL_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3, -+ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, -+ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, -+ AIROHA_PCS_PMA_DISB_EYECNT_RDY); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_EYECNT_RDY); -+ -+ usleep_range(1000, 1500); -+} -+ -+static void an7583_pcs_common_phya_eye_eo_read(struct airoha_pcs_priv *priv, -+ int index, u32 *heo, u32 *veo) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 eo_buf[EO_BUF_MAX]; -+ u32 eye_el, eye_er; -+ u32 feos; -+ u32 val; -+ int i; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_6, -+ AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN | -+ AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN | -+ AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN | -+ AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN); -+ -+ usleep_range(50, 100); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FLL_6, -+ AIROHA_PCS_PMA_LNX_SW_FLL_4_LATCH_EN | -+ AIROHA_PCS_PMA_LNX_SW_FLL_3_LATCH_EN | -+ AIROHA_PCS_PMA_LNX_SW_FLL_2_LATCH_EN | -+ AIROHA_PCS_PMA_LNX_SW_FLL_1_LATCH_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DEBUG_0, -+ AIROHA_PCS_PMA_RO_TOGGLE); -+ -+ usleep_range(100, 200); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DEBUG_0, -+ AIROHA_PCS_PMA_RO_TOGGLE); -+ -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_10, &val); -+ eye_el = FIELD_GET(AIROHA_PCS_PMA_EYE_EL, val); -+ eye_er = FIELD_GET(AIROHA_PCS_PMA_EYE_ER, val); -+ -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_11, &val); -+ eo_buf[EYE_EU] = FIELD_GET(AIROHA_PCS_PMA_EYE_EU, val); -+ eo_buf[EYE_EB] = FIELD_GET(AIROHA_PCS_PMA_EYE_EB, val); -+ -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_ADD_RX2ANA_1, &val); -+ eo_buf[DAC_EYE] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_EYE, val); -+ eo_buf[DAC_D0] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_D0, val); -+ eo_buf[DAC_D1] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_D1, val); -+ eo_buf[DAC_E0] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_E0, val); -+ -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_ADD_RX2ANA_2, &val); -+ eo_buf[FEOS] = FIELD_GET(AIROHA_PCS_PMA_RX_FEOS_OUT, val); -+ eo_buf[DAC_E1] = FIELD_GET(AIROHA_PCS_PMA_RX_DAC_E1, val); -+ -+ feos = eo_buf[FEOS]; -+ -+ for (i = 0; i < ARRAY_SIZE(eo_buf); i++) { -+ if ((eo_buf[i] == feos) && (eo_buf[i] >= 32)) -+ eo_buf[i] = eo_buf[i] - 64; -+ else if (eo_buf[i] >= 64) -+ eo_buf[i] = eo_buf[i] - 128; -+ } -+ -+ /* Check if CLK unlocking happens (E0 result validity) */ -+ regmap_read(pcs_pma, AIROHA_PCS_PMA_RX_TORGS_DEBUG_5, &val); -+ if (!FIELD_GET(AIROHA_PCS_PMA_HEO_RDY, val)) { -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_0, -+ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_LPF_RSTB); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0, -+ AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB); -+ -+ usleep_range(500, 700); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_0, -+ AIROHA_PCS_PMA_FORCE_DA_XPON_CDR_LPF_RSTB); -+ -+ usleep_range(500, 700); -+ } -+ -+ *heo = abs(eye_er - eye_el); -+ *veo = abs(eo_buf[EYE_EU] - eo_buf[EYE_EB]); -+} -+ -+static void an7583_pcs_common_phya_eye_eo(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface, -+ u32 *heo, u32 *veo) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, -+ AIROHA_PCS_PMA_DISB_EYE_RESET_PLU_O); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, -+ AIROHA_PCS_PMA_DISB_EYE_TOP_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); -+ -+ if (interface == PHY_INTERFACE_MODE_10GBASER || -+ interface == PHY_INTERFACE_MODE_USXGMII) -+ usleep_range(5500, 6000); -+ else -+ msleep(55); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_2, -+ AIROHA_PCS_PMA_DISB_DA_XPON_CDR_PR_PIEYE | -+ AIROHA_PCS_PMA_DISB_DA_XPON_RX_DAC_EYE); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_DISB_EYEDUR_INIT_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_7, -+ AIROHA_PCS_PMA_DISB_EYECNT_RX_RST_B); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_EYE_TOP_EYECNT_CTRL_1, -+ AIROHA_PCS_PMA_DISB_EYEDUR_EN); -+ -+ an7583_pcs_common_phya_eye_eo_read(priv, index, heo, veo); -+ -+ /* Clear Eye SW value */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_RESET_PLU_O); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_8, -+ AIROHA_PCS_PMA_DISB_EYE_TOP_EN); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_9, -+ AIROHA_PCS_PMA_FORCE_EYE_TOP_EN); -+ -+ /* Reset PICal Rdy */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_3, -+ AIROHA_PCS_PMA_DISB_RQ_PI_CAL_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_3, -+ AIROHA_PCS_PMA_FORCE_EQ_PI_CAL_RDY); -+ -+ /* Reset Eyecnt Rdy */ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_DISB_MODE_5, -+ AIROHA_PCS_PMA_DISB_EYECNT_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_FORCE_MODE_6, -+ AIROHA_PCS_PMA_FORCE_EYECNT_RDY); -+} -+ -+static void an7583_pcs_common_phya_eo_scan(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 best_heo = 0, best_veo = 0; -+ u32 leq_gain, best_leq_gain; -+ u32 best_leq_peacking = 0; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ case PHY_INTERFACE_MODE_5GBASER: -+ leq_gain = 3; -+ break; -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_USXGMII: -+ leq_gain = 1; -+ break; -+ default: -+ return; -+ } -+ -+ best_leq_gain = leq_gain; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_PR_PIEYE_PWDB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_PR_PIEYE_PWDB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_PR_PIEYE_PWDB); -+ -+ an7583_pcs_common_phya_eye_setting(priv, index, interface); -+ -+ /* EYE Open */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PHY_EQ_CTRL_0, -+ AIROHA_PCS_PMA_EQ_EN_DELAY, -+ FIELD_PREP(AIROHA_PCS_PMA_EQ_EN_DELAY, 0x80)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_RX_PI_CAL, -+ AIROHA_PCS_PMA_KPGAIN, -+ FIELD_PREP(AIROHA_PCS_PMA_KPGAIN, 0x4)); -+ -+ for (; leq_gain <= FIELD_MAX(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL); leq_gain++) { -+ u32 leq_peaking; -+ u32 heo, veo; -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL | -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_GAIN_CTRL | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, leq_gain)); -+ -+ for (leq_peaking = 0; leq_peaking <= FIELD_MAX(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL); leq_peaking++) { -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_RX_FE_PEAKING_CTRL | -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, leq_peaking)); -+ -+ usleep_range(500, 700); -+ -+ an7583_pcs_common_phya_eye_cal(priv, index); -+ an7583_pcs_common_phya_eye_eo(priv, index, interface, &heo, &veo); -+ -+ if (veo > 53 && best_veo > 53) { -+ if (heo > best_heo) { -+ best_heo = heo; -+ best_veo = veo; -+ best_leq_peacking = leq_peaking; -+ best_leq_gain = leq_gain; -+ } else if (heo == best_heo && veo > best_veo) { -+ best_heo = heo; -+ best_veo = veo; -+ best_leq_peacking = leq_peaking; -+ best_leq_gain = leq_gain; -+ } -+ } else { -+ if (veo > best_veo) { -+ best_heo = heo; -+ best_veo = veo; -+ best_leq_peacking = leq_peaking; -+ best_leq_gain = leq_gain; -+ } -+ } -+ } -+ } -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_FE_GAIN_CTRL, -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_GAIN_CTRL, best_leq_gain)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_JCPLL_SDM_SCAN, -+ AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, -+ FIELD_PREP(AIROHA_PCS_PMA_FORCE_DA_RX_FE_PEAKING_CTRL, best_leq_peacking)); -+} -+ -+static void an7583_pcs_common_phya_rxrdy(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ u32 xfi_rx_term_sel = 0x1; -+ // int efuse_valid; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_FORCE_RX_RDY); -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N); -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_RX_FIFO_RST_N); -+ -+ /* TODO HANDLE EFUSE */ -+ regmap_update_bits(priv->pcs_ana, AIROHA_PCS_ANA_PXP_RX_SIGDET_NOVTH, -+ AIROHA_PCS_ANA_RX_FE_50OHMS_SEL, -+ FIELD_PREP(AIROHA_PCS_ANA_RX_FE_50OHMS_SEL, -+ xfi_rx_term_sel)); -+} -+ -+static void an7583_pcs_common_phya_bist_setting(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_write(pcs_pma, AIROHA_PCS_PMA_BISTCTL_ALIGN_PAT, -+ 0x8ff1fd53); -+ regmap_write(pcs_pma, AIROHA_PCS_PMA_BISTCTL_PRBS_INITIAL_SEED, -+ 0xFF1FD53); -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD, -+ AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK, -+ FIELD_PREP(AIROHA_PCS_PMA_BISTCTL_PRBS_FAIL_THRESHOLD_MASK, 0x1)); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_BISTCTL_CONTROL, -+ AIROHA_PCS_PMA_BISTCTL_PAT_SEL, -+ AIROHA_PCS_PMA_BISTCTL_PAT_SEL_PRBS31); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_BISTCTL_POLLUTION, -+ AIROHA_PCS_PMA_BIST_TX_DATA_POLLUTION_LATCH); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_SS_BIST_1, -+ AIROHA_PCS_PMA_LNX_BISTCTL_BIT_ERROR_RST_SEL | -+ AIROHA_PCS_PMA_ANLT_PX_LNX_LT_LOS); -+} -+ -+static void an7583_pcs_first_plug_in(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ const struct airoha_pcs_match_data *data = priv->data; -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ an7583_pcs_common_phya_rx_preset(priv, index, interface); -+ if (data->port_type == AIROHA_PCS_PON || -+ data->port_type == AIROHA_PCS_PCIE) -+ an7583_pcs_common_phya_tdc_off(priv, index); -+ an7583_pcs_common_phya_rx_on(priv, index); -+ an7583_pcs_common_phya_l2d(priv, index); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_REF_RST_N); -+ -+ usleep_range(100, 200); -+ -+ an7583_pcs_common_phya_rx_oscal(priv, index); -+ an7583_pcs_common_phya_pical(priv, index); -+ an7583_pcs_common_phya_pdos(priv, index); -+ an7583_pcs_common_phya_feos(priv, index); -+ an7583_pcs_common_phya_sdcal(priv, index); -+ an7583_pcs_common_phya_phy_status(priv, index); -+ -+ an7583_pcs_dig_reset_release(priv, index); -+ -+ an7583_pcs_common_phya_l2d(priv, index); -+ -+ if (data->port_type == AIROHA_PCS_PON) -+ an7583_pcs_common_phya_eo_scan(priv, index, interface); -+ an7583_pcs_common_phya_rxrdy(priv, index); -+ if (data->port_type == AIROHA_PCS_PON || -+ data->port_type == AIROHA_PCS_PCIE) -+ an7583_pcs_common_phya_bist_setting(priv, index); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_ADD_XPON_MODE_1, -+ AIROHA_PCS_PMA_TX_BIST_GEN_EN | -+ AIROHA_PCS_PMA_R2T_MODE); -+} -+ -+static void an7583_pcs_ana_reset_release(struct airoha_pcs_priv *priv, -+ int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_XFI_RXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_TXPCS_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_XFI_RXPCS_BIST_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_HSG_RXPCS_RST_N | -+ AIROHA_PCS_PMA_SW_HSG_TXPCS_RST_N); -+ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_SW_RST_SET, -+ AIROHA_PCS_PMA_SW_XFI_RXMAC_RST_N | -+ AIROHA_PCS_PMA_SW_XFI_TXMAC_RST_N); -+} -+ -+int an7583_pcs_usb_phya_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ struct airoha_pcs_maps *maps = &priv->maps[index]; -+ -+ regmap_set_bits(maps->multi_sgmii, -+ AIROHA_PCS_MULTI_SGMII_MSG_RX_LIK_STS_1, -+ AIROHA_PCS_PAUSE_STS_P2 | AIROHA_PCS_PAUSE_STS_P1); -+ -+ return phy_set_mode_ext(priv->phy, PHY_MODE_ETHERNET, interface); -+} -+ -+int an7583_pcs_common_phya_bringup(struct airoha_pcs_priv *priv, -+ int index, phy_interface_t interface) -+{ -+ if (priv->phy) -+ return an7583_pcs_usb_phya_bringup(priv, index, interface); -+ -+ an7583_pcs_dig_reset_hold(priv, index); -+ -+ an7583_pcs_cfg_phy_type(priv, index, interface); -+ -+ an7583_pcs_common_phya_txpll_on(priv, index); -+ -+ an7583_pcs_common_phya_tx_on(priv, index); -+ -+ an7583_pcs_first_plug_in(priv, index, interface); -+ -+ an7583_pcs_ana_reset_release(priv, index); -+ -+ return 0; -+} -+ -+void an7583_pcs_common_phya_link_up(struct airoha_pcs_priv *priv, int index) -+{ -+ struct regmap *pcs_pma = priv->pcs_pma[index]; -+ -+ if (priv->phy) -+ return; -+ -+ /* First CDR reset */ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB); -+ -+ usleep_range(700, 1000); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); -+ -+ usleep_range(100, 200); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_RSTB | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_RSTB); -+ -+ regmap_update_bits(pcs_pma, AIROHA_PCS_PMA_PXP_CDR_LPF_LCK_2DATA, -+ AIROHA_PCS_PMA_FORCE_SEL_DA_CDR_LPF_LCK2DATA | -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA, -+ AIROHA_PCS_PMA_FORCE_DA_CDR_LPF_LCK2DATA); -+ -+ /* Then RX Rdy reset */ -+ regmap_set_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_DISB_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_RDY); -+ -+ regmap_clear_bits(pcs_pma, AIROHA_PCS_PMA_RX_CTRL_SEQUENCE_FORCE_CTRL_1, -+ AIROHA_PCS_PMA_DISB_RX_RDY); -+} diff --git a/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch b/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch deleted file mode 100644 index b78cc3455fe..00000000000 --- a/target/linux/airoha/patches-6.12/604-02-net-ethernet-airoha-define-sport-value-for-GDM3.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 6548e580509397a622b7c504a79de93414771459 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 25 Jun 2025 00:04:36 +0200 -Subject: [PATCH 6/6] net: ethernet: airoha: define sport value for GDM3 - -On Airoha AN7583, the Serdes Ethernet goes through the GDM3 port. -To correctly receive packet for QDMA, add the sport value to identify -packet from GDM3 port. - -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -585,6 +585,9 @@ static int airoha_qdma_get_gdm_port(stru - case 0x18: - port = 3; /* GDM4 */ - break; -+ case 0x16: -+ port = 2; /* GDM3 */ -+ break; - case 0x10 ... 0x14: - port = 0; /* GDM1 */ - break; diff --git a/target/linux/airoha/patches-6.12/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch b/target/linux/airoha/patches-6.12/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch deleted file mode 100644 index a505475097b..00000000000 --- a/target/linux/airoha/patches-6.12/605-net-pcs-airoha-add-support-for-optional-xfi-reset-li.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 961800f3badd72e4efda39f219ac4cbec5791433 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 26 Jul 2025 22:58:10 +0200 -Subject: [PATCH 7/8] net: pcs: airoha: add support for optional xfi reset line - -On Airoha AN7583 there is a dedicated reset line for the PON XFI Serdes. -This is needed to permit changing the WAN sel register or the system -will stall on accessing the XFI register. - -Add support for this optional dedicated reset to permit correct -configuration of the PON Serdes. - -Signed-off-by: Christian Marangi ---- - drivers/net/pcs/airoha/pcs-airoha-common.c | 12 ++++++++++++ - drivers/net/pcs/airoha/pcs-airoha.h | 1 + - 2 files changed, 13 insertions(+) - ---- a/drivers/net/pcs/airoha/pcs-airoha-common.c -+++ b/drivers/net/pcs/airoha/pcs-airoha-common.c -@@ -144,6 +144,10 @@ static int airoha_pcs_setup_scu(struct a - const struct airoha_pcs_match_data *data = priv->data; - int ret; - -+ ret = reset_control_assert(priv->xfi_rst); -+ if (ret) -+ return ret; -+ - switch (data->port_type) { - case AIROHA_PCS_ETH: - airoha_pcs_setup_scu_eth(priv, interface); -@@ -161,6 +165,10 @@ static int airoha_pcs_setup_scu(struct a - break; - } - -+ ret = reset_control_deassert(priv->xfi_rst); -+ if (ret) -+ return ret; -+ - /* TODO better handle reset from MAC */ - ret = reset_control_bulk_assert(ARRAY_SIZE(priv->rsts), - priv->rsts); -@@ -1298,6 +1306,10 @@ static int airoha_pcs_probe(struct platf - if (ret) - return dev_err_probe(dev, ret, "failed to get bulk reset lines\n"); - -+ priv->xfi_rst = devm_reset_control_get_optional_exclusive(dev, "xfi"); -+ if (IS_ERR(priv->xfi_rst)) -+ return dev_err_probe(dev, PTR_ERR(priv->xfi_rst), "failed to get xfi reset lines\n"); -+ - /* For Ethernet PCS, read the AN7581 SoC revision to check if - * manual rx calibration is needed. This is only limited to - * any SoC revision before E2. ---- a/drivers/net/pcs/airoha/pcs-airoha.h -+++ b/drivers/net/pcs/airoha/pcs-airoha.h -@@ -1654,6 +1654,7 @@ struct airoha_pcs_priv { - struct regmap *pcs_ana; - struct regmap_field **pcs_ana_fields[2]; - -+ struct reset_control *xfi_rst; - struct reset_control_bulk_data rsts[AIROHA_PCS_MAX_NUM_RSTS]; - - struct phy *phy; diff --git a/target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch b/target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch deleted file mode 100644 index d43d3303a07..00000000000 --- a/target/linux/airoha/patches-6.12/606-net-airoha-disable-external-phy-code-if-PCS_AIROHA-i.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 843e2892f2d9353bf039e0dfb5442a600e75009e Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Thu, 9 Oct 2025 23:46:08 +0300 -Subject: [PATCH] net: airoha: disable external phy code if PCS_AIROHA is not - enabled - -External phy code breaks building for EN7523, so disable it if -PCS_AIROHA is not selected. - -Signed-off-by: Mikhail Kshevetskiy ---- - drivers/net/ethernet/airoha/airoha_eth.c | 16 ++++++++++++++++ - drivers/net/ethernet/airoha/airoha_eth.h | 2 ++ - 2 files changed, 18 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -72,10 +72,12 @@ static void airoha_qdma_irq_disable(stru - airoha_qdma_set_irqmask(irq_bank, index, mask, 0); - } - -+#if defined(CONFIG_PCS_AIROHA) - static bool airhoa_is_phy_external(struct airoha_gdm_port *port) - { - return port->id != 1; - } -+#endif - - static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) - { -@@ -1725,6 +1727,7 @@ static int airoha_dev_open(struct net_de - struct airoha_qdma *qdma = port->qdma; - u32 pse_port = FE_PSE_PORT_PPE1; - -+#if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { - err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0); - if (err) { -@@ -1735,6 +1738,7 @@ static int airoha_dev_open(struct net_de - - phylink_start(port->phylink); - } -+#endif - - netif_tx_start_all_queues(dev); - err = airoha_set_vip_for_gdm_port(port, true); -@@ -1797,10 +1801,12 @@ static int airoha_dev_stop(struct net_de - } - } - -+#if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { - phylink_stop(port->phylink); - phylink_disconnect_phy(port->phylink); - } -+#endif - - return 0; - } -@@ -2990,6 +2996,7 @@ bool airoha_is_valid_gdm_port(struct air - return false; - } - -+#if defined(CONFIG_PCS_AIROHA) - static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy, - unsigned int mode, phy_interface_t interface, - int speed, int duplex, bool tx_pause, bool rx_pause) -@@ -3102,6 +3109,7 @@ static int airoha_setup_phylink(struct n - - return err; - } -+#endif - - static int airoha_alloc_gdm_port(struct airoha_eth *eth, - struct device_node *np) -@@ -3176,11 +3184,13 @@ static int airoha_alloc_gdm_port(struct - port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; - eth->ports[p] = port; - -+#if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { - err = airoha_setup_phylink(dev); - if (err) - return err; - } -+#endif - - return airoha_metadata_dst_alloc(port); - } -@@ -3310,8 +3320,10 @@ error_napi_stop: - continue; - - if (port->dev->reg_state == NETREG_REGISTERED) { -+#if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) - phylink_destroy(port->phylink); -+#endif - unregister_netdev(port->dev); - } - airoha_metadata_dst_free(port); -@@ -3338,8 +3350,10 @@ static void airoha_remove(struct platfor - if (!port) - continue; - -+#if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) - phylink_destroy(port->phylink); -+#endif - unregister_netdev(port->dev); - airoha_metadata_dst_free(port); - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -542,8 +542,10 @@ struct airoha_gdm_port { - int id; - int nbq; - -+#if defined(CONFIG_PCS_AIROHA) - struct phylink *phylink; - struct phylink_config phylink_config; -+#endif - - struct airoha_hw_stats stats; - diff --git a/target/linux/airoha/patches-6.12/801-01-net-phy-add-PHY_DETACH_NO_HW_RESET-PHY-flag.patch b/target/linux/airoha/patches-6.12/801-01-net-phy-add-PHY_DETACH_NO_HW_RESET-PHY-flag.patch deleted file mode 100644 index 0c273f000fe..00000000000 --- a/target/linux/airoha/patches-6.12/801-01-net-phy-add-PHY_DETACH_NO_HW_RESET-PHY-flag.patch +++ /dev/null @@ -1,129 +0,0 @@ -From f2c6f8711c3866caafee997cfa60af4f38879be0 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 25 Jun 2025 00:45:11 +0200 -Subject: [PATCH 1/2] net: phy: add PHY_DETACH_NO_HW_RESET PHY flag - -Some PHY require a firmware to correctly work and such firmware might -get reset when the GPIO reset is assert. - -This is the case for the Aeonsemi PHY where when the PHY is torn down, -phy_detach() is called that assert the GPIO reset pin resetting the -firmware. - -To handle this introduce a flag, PHY_DETACH_NO_HW_RESET that instruct -phy_detach() to skip asserting the GPIO reset on detaching the PHY. - -The PHY is still reset in all other case where it's removed or the PHY -fails to probe. - -Signed-off-by: Christian Marangi ---- - drivers/net/phy/as21xxx.c | 10 ++++++++++ - drivers/net/phy/phy_device.c | 3 ++- - include/linux/phy.h | 1 + - 3 files changed, 13 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/as21xxx.c -+++ b/drivers/net/phy/as21xxx.c -@@ -965,6 +965,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1), -@@ -977,6 +978,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1), -@@ -989,6 +991,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1), -@@ -1001,6 +1004,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1), -@@ -1013,6 +1017,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1), -@@ -1025,6 +1030,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1), -@@ -1037,6 +1043,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1), -@@ -1049,6 +1056,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1), -@@ -1061,6 +1069,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1), -@@ -1073,6 +1082,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -+ .flags = PHY_DETACH_NO_RESET, - }, - }; - module_phy_driver(as21xxx_drivers); ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -2069,7 +2069,8 @@ void phy_detach(struct phy_device *phyde - device_release_driver(&phydev->mdio.dev); - - /* Assert the reset signal */ -- phy_device_reset(phydev, 1); -+ if (!phydev->drv || !(phydev->drv->flags & PHY_DETACH_NO_HW_RESET)) -+ phy_device_reset(phydev, 1); - - /* - * The phydev might go away on the put_device() below, so avoid ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -90,6 +90,7 @@ extern const int phy_10gbit_features_arr - #define PHY_RST_AFTER_CLK_EN 0x00000002 - #define PHY_POLL_CABLE_TEST 0x00000004 - #define PHY_ALWAYS_CALL_SUSPEND 0x00000008 -+#define PHY_DETACH_NO_HW_RESET 0x00000010 - #define MDIO_DEVICE_IS_PHY 0x80000000 - - /** diff --git a/target/linux/airoha/patches-6.12/801-02-net-phy-as21xxx-add-flag-PHY_DETACH_NO_HW_RESET.patch b/target/linux/airoha/patches-6.12/801-02-net-phy-as21xxx-add-flag-PHY_DETACH_NO_HW_RESET.patch deleted file mode 100644 index 029bdb5ab15..00000000000 --- a/target/linux/airoha/patches-6.12/801-02-net-phy-as21xxx-add-flag-PHY_DETACH_NO_HW_RESET.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 7ad1470c3d08c1abea747aa0c789e924f63fcbc4 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 25 Jun 2025 00:51:45 +0200 -Subject: [PATCH 2/2] net: phy: as21xxx: add flag PHY_DETACH_NO_HW_RESET - -Add flag PHY_DETACH_NO_HW_RESET to handle firmware getting reset on -calling phy_detach() if the GPIO reset PIN is defined in DT. - -This will skip the firmware from getting reset permitting the PHY to -continue work when the PHY is torn down and gets up again. - -Signed-off-by: Christian Marangi ---- - drivers/net/phy/as21xxx.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/as21xxx.c -+++ b/drivers/net/phy/as21xxx.c -@@ -965,7 +965,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1), -@@ -978,7 +978,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1), -@@ -991,7 +991,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1), -@@ -1004,7 +1004,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1), -@@ -1017,7 +1017,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1), -@@ -1030,7 +1030,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1), -@@ -1043,7 +1043,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1), -@@ -1056,7 +1056,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1), -@@ -1069,7 +1069,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1), -@@ -1082,7 +1082,7 @@ static struct phy_driver as21xxx_drivers - .led_hw_control_set = as21xxx_led_hw_control_set, - .led_hw_control_get = as21xxx_led_hw_control_get, - .led_polarity_set = as21xxx_led_polarity_set, -- .flags = PHY_DETACH_NO_RESET, -+ .flags = PHY_DETACH_NO_HW_RESET, - }, - }; - module_phy_driver(as21xxx_drivers); diff --git a/target/linux/airoha/patches-6.12/802-01-net-phy-as21xxx-handle-corner-case-with-link-and-aut.patch b/target/linux/airoha/patches-6.12/802-01-net-phy-as21xxx-handle-corner-case-with-link-and-aut.patch deleted file mode 100644 index 6e599cdd3f0..00000000000 --- a/target/linux/airoha/patches-6.12/802-01-net-phy-as21xxx-handle-corner-case-with-link-and-aut.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0146a02d9d182796c3d8e4a432c4d94cac042f8e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 7 Jul 2025 18:58:25 +0200 -Subject: [PATCH 1/4] net: phy: as21xxx: handle corner case with link and - autoneg complete - -Add missing case in custom read_link, when autoneg is started, autoneg -complete bit is reset but link is still not up. - -Fixes: 830877d89edc ("net: phy: Add support for Aeonsemi AS21xxx PHYs") -Signed-off-by: Christian Marangi ---- - drivers/net/phy/as21xxx.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/net/phy/as21xxx.c -+++ b/drivers/net/phy/as21xxx.c -@@ -658,6 +658,13 @@ static int as21xxx_read_link(struct phy_ - return status; - - phydev->link = !!(status & MDIO_STAT1_LSTATUS); -+ phydev->autoneg_complete = !!(status & MDIO_AN_STAT1_COMPLETE); -+ -+ /* Consider the case that autoneg was started and "aneg complete" -+ * bit has been reset, but "link up" bit not yet. -+ */ -+ if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) -+ phydev->link = 0; - - return 0; - } diff --git a/target/linux/airoha/patches-6.12/802-02-net-phy-as21xxx-fix-read_status-speed-handling.patch b/target/linux/airoha/patches-6.12/802-02-net-phy-as21xxx-fix-read_status-speed-handling.patch deleted file mode 100644 index 4010c4093b0..00000000000 --- a/target/linux/airoha/patches-6.12/802-02-net-phy-as21xxx-fix-read_status-speed-handling.patch +++ /dev/null @@ -1,156 +0,0 @@ -From d90186b1e48dd4a428abf889b1eb17d2469de08b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 8 Jul 2025 10:50:42 +0200 -Subject: [PATCH 2/4] net: phy: as21xxx: fix read_status speed handling - -With further test with 2.5G NIC it was discovered that -phy_resolve_aneg_linkmode is not enough to detect speed higher that 1G -when autoneg is enabled. - -Also in the switch case there is a typo where the speed mask is AND with -VEND1_SPEED_STATUS instead of the correct mask VEND1_SPEED_MASK. - -Rework the read_status code to always read the speed from the vendor -register and parse the generic bit only for the pause frame. - -Fixes: 830877d89edc ("net: phy: Add support for Aeonsemi AS21xxx PHYs") -Signed-off-by: Christian Marangi ---- - drivers/net/phy/as21xxx.c | 96 +++++++++++++++++++++------------------ - 1 file changed, 53 insertions(+), 43 deletions(-) - ---- a/drivers/net/phy/as21xxx.c -+++ b/drivers/net/phy/as21xxx.c -@@ -671,7 +671,7 @@ static int as21xxx_read_link(struct phy_ - - static int as21xxx_read_c22_lpa(struct phy_device *phydev) - { -- int lpagb; -+ int lpagb, lpa; - - /* MII_STAT1000 are only filled in the mapped C22 - * in C45, use that to fill lpagb values and check. -@@ -698,12 +698,20 @@ static int as21xxx_read_c22_lpa(struct p - mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, - lpagb); - -+ lpa = phy_read_mmd(phydev, MDIO_MMD_AN, -+ AS21XXX_MDIO_AN_C22 + MII_LPA); -+ if (lpa < 0) -+ return lpa; -+ -+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); -+ - return 0; - } - - static int as21xxx_read_status(struct phy_device *phydev) - { - int bmcr, old_link = phydev->link; -+ int speed; - int ret; - - ret = as21xxx_read_link(phydev, &bmcr); -@@ -720,58 +728,60 @@ static int as21xxx_read_status(struct ph - phydev->asym_pause = 0; - - if (phydev->autoneg == AUTONEG_ENABLE) { -- ret = genphy_c45_read_lpa(phydev); -- if (ret) -- return ret; -+ if (!phydev->autoneg_complete) { -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, -+ 0); -+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -+ return 0; -+ } - - ret = as21xxx_read_c22_lpa(phydev); - if (ret) - return ret; -- -- phy_resolve_aneg_linkmode(phydev); - } else { -- int speed; -- - linkmode_zero(phydev->lp_advertising); -+ } - -- speed = phy_read_mmd(phydev, MDIO_MMD_VEND1, -- VEND1_SPEED_STATUS); -- if (speed < 0) -- return speed; -- -- switch (speed & VEND1_SPEED_STATUS) { -- case VEND1_SPEED_10000: -- phydev->speed = SPEED_10000; -+ speed = phy_read_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_SPEED_STATUS); -+ if (speed < 0) -+ return speed; -+ -+ switch (speed & VEND1_SPEED_MASK) { -+ case VEND1_SPEED_10000: -+ phydev->speed = SPEED_10000; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_5000: -+ phydev->speed = SPEED_5000; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_2500: -+ phydev->speed = SPEED_2500; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ if (bmcr & BMCR_FULLDPLX) - phydev->duplex = DUPLEX_FULL; -- break; -- case VEND1_SPEED_5000: -- phydev->speed = SPEED_5000; -- phydev->duplex = DUPLEX_FULL; -- break; -- case VEND1_SPEED_2500: -- phydev->speed = SPEED_2500; -- phydev->duplex = DUPLEX_FULL; -- break; -- case VEND1_SPEED_1000: -- phydev->speed = SPEED_1000; -- if (bmcr & BMCR_FULLDPLX) -- phydev->duplex = DUPLEX_FULL; -- else -- phydev->duplex = DUPLEX_HALF; -- break; -- case VEND1_SPEED_100: -- phydev->speed = SPEED_100; -- phydev->duplex = DUPLEX_FULL; -- break; -- case VEND1_SPEED_10: -- phydev->speed = SPEED_10; -- phydev->duplex = DUPLEX_FULL; -- break; -- default: -- return -EINVAL; -- } -+ else -+ phydev->duplex = DUPLEX_HALF; -+ break; -+ case VEND1_SPEED_100: -+ phydev->speed = SPEED_100; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ case VEND1_SPEED_10: -+ phydev->speed = SPEED_10; -+ phydev->duplex = DUPLEX_FULL; -+ break; -+ default: -+ return -EINVAL; - } - -+ if (phydev->autoneg == AUTONEG_ENABLE) -+ phy_resolve_aneg_pause(phydev); -+ - return 0; - } - diff --git a/target/linux/airoha/patches-6.12/802-03-net-phy-as21xxx-force-C45-OPs-for-AUTONEG.patch b/target/linux/airoha/patches-6.12/802-03-net-phy-as21xxx-force-C45-OPs-for-AUTONEG.patch deleted file mode 100644 index 19118db7864..00000000000 --- a/target/linux/airoha/patches-6.12/802-03-net-phy-as21xxx-force-C45-OPs-for-AUTONEG.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6003da596beb6b8974e61b7ff494476a323fbef5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 8 Jul 2025 11:29:49 +0200 -Subject: [PATCH 3/4] net: phy: as21xxx: force C45 OPs for AUTONEG - -With further testing with 2.5G NIC, it was discovered that the PHY -require the C45 OPs to configure and restart ANEG or speed higher than -1G doesn't function correctly. - -To force C45 OPs with generic PHY function, clear the C22 bit from -devices_in_package bitmask. - -Fixes: 830877d89edc ("net: phy: Add support for Aeonsemi AS21xxx PHYs") -Signed-off-by: Christian Marangi ---- - drivers/net/phy/as21xxx.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/net/phy/as21xxx.c -+++ b/drivers/net/phy/as21xxx.c -@@ -616,6 +616,13 @@ static int as21xxx_probe(struct phy_devi - if (ret) - return ret; - -+ /* Even if PHY declare support for Clause 22 register, -+ * Clause 45 register should be used for ANEG configuration -+ * and restart. Clear the C22 bit for devices_in_package to -+ * force C45 generic OPs in generic PHY ANGE OPs. -+ */ -+ phydev->c45_ids.devices_in_package &= ~BIT(0); -+ - ret = aeon_ipc_sync_parity(phydev, priv); - if (ret) - return ret; diff --git a/target/linux/airoha/patches-6.12/804-net-phy-as21xxx-implement-read-workaround-for-C45-re.patch b/target/linux/airoha/patches-6.12/804-net-phy-as21xxx-implement-read-workaround-for-C45-re.patch deleted file mode 100644 index 0c24e9e20f8..00000000000 --- a/target/linux/airoha/patches-6.12/804-net-phy-as21xxx-implement-read-workaround-for-C45-re.patch +++ /dev/null @@ -1,132 +0,0 @@ -From fabaa8a7183d10217e14af437fd3805bd6dd9eba Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 18 Oct 2025 04:12:41 +0200 -Subject: [PATCH] net: phy: as21xxx: implement read workaround for C45 read - -This PHY have lots of problems with MDIO read operation. We somehow -workaround this with using C45 operation for pretty much everything but -this is not enough. The reference code for this PHY makes a write to an -unused PHY to workaround this read problem. This was also confirmed by -Aeonsemi. - -Various test were made to try to workaround this ins alternative way -than the random write. - -One effective solution was to limit the write only to BMSR. And also -write to BMSR is safe since they are only read only registers. - -This is only done for read operation as write operation doesn't suffer -from this problem. - -Worth to mention that when multiple Aeonsemi PHY are mounted, the -workaround doesn't work if we write to another Aeonsemi PHY. - -Signed-off-by: Christian Marangi ---- - drivers/net/phy/as21xxx.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/phy/as21xxx.c -+++ b/drivers/net/phy/as21xxx.c -@@ -967,6 +967,21 @@ out: - return ret; - } - -+static int as21xxx_read_mmd(struct phy_device *phydev, int devad, -+ u16 regnum) -+{ -+ struct mii_bus *bus = phydev->mdio.bus; -+ int val; -+ -+ val = __mdiobus_c45_read(bus, phydev->mdio.addr, devad, -+ regnum); -+ -+ /* FIXME: verify if it's actually ok to limit this to MII_BMSR */ -+ __mdiobus_write(bus, 0x0, MII_BMSR, 0x1); -+ -+ return val; -+} -+ - static struct phy_driver as21xxx_drivers[] = { - { - /* PHY expose in C45 as 0x7500 0x9410 -@@ -984,6 +999,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -997,6 +1013,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1010,6 +1027,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1023,6 +1041,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1036,6 +1055,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1049,6 +1069,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1062,6 +1083,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1075,6 +1097,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1088,6 +1111,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, -@@ -1101,6 +1125,7 @@ static struct phy_driver as21xxx_drivers - .probe = as21xxx_probe, - .match_phy_device = as21xxx_match_phy_device, - .read_status = as21xxx_read_status, -+ .read_mmd = as21xxx_read_mmd, - .led_brightness_set = as21xxx_led_brightness_set, - .led_hw_is_supported = as21xxx_led_hw_is_supported, - .led_hw_control_set = as21xxx_led_hw_control_set, diff --git a/target/linux/airoha/patches-6.12/885-i2c-mt7621-optional-reset.patch b/target/linux/airoha/patches-6.12/885-i2c-mt7621-optional-reset.patch deleted file mode 100644 index 1fad1bdd01f..00000000000 --- a/target/linux/airoha/patches-6.12/885-i2c-mt7621-optional-reset.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/i2c/busses/i2c-mt7621.c -+++ b/drivers/i2c/busses/i2c-mt7621.c -@@ -85,7 +85,7 @@ static void mtk_i2c_reset(struct mtk_i2c - { - int ret; - -- ret = device_reset(i2c->adap.dev.parent); -+ ret = device_reset_optional(i2c->adap.dev.parent); - if (ret) - dev_err(i2c->dev, "I2C reset failed!\n"); - diff --git a/target/linux/airoha/patches-6.12/886-uart-add-en7523-support.patch b/target/linux/airoha/patches-6.12/886-uart-add-en7523-support.patch deleted file mode 100644 index 486208f71ad..00000000000 --- a/target/linux/airoha/patches-6.12/886-uart-add-en7523-support.patch +++ /dev/null @@ -1,206 +0,0 @@ ---- /dev/null -+++ b/drivers/tty/serial/8250/8250_en7523.c -@@ -0,0 +1,94 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Airoha EN7523 driver. -+ * -+ * Copyright (c) 2022 Genexis Sweden AB -+ * Author: Benjamin Larsson -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "8250.h" -+ -+ -+/* The Airoha UART is 16550-compatible except for the baud rate calculation. -+ * -+ * crystal_clock = 20 MHz -+ * xindiv_clock = crystal_clock / clock_div -+ * (x/y) = XYD, 32 bit register with 16 bits of x and and then 16 bits of y -+ * clock_div = XINCLK_DIVCNT (default set to 10 (0x4)), -+ * - 3 bit register [ 1, 2, 4, 8, 10, 12, 16, 20 ] -+ * -+ * baud_rate = ((xindiv_clock) * (x/y)) / ([BRDH,BRDL] * 16) -+ * -+ * XYD_y seems to need to be larger then XYD_x for things to work. -+ * Setting [BRDH,BRDL] to [0,1] and XYD_y to 65000 give even values -+ * for usual baud rates. -+ * -+ * Selecting divider needs to fulfill -+ * 1.8432 MHz <= xindiv_clk <= APB clock / 2 -+ * The clocks are unknown but a divider of value 1 did not work. -+ * -+ * Optimally the XYD, BRD and XINCLK_DIVCNT registers could be searched to -+ * find values that gives the least error for every baud rate. But searching -+ * the space takes time and in practise only a few rates are of interest. -+ * With some value combinations not working a tested subset is used giving -+ * a usable range from 110 to 460800 baud. -+ */ -+ -+#define CLOCK_DIV_TAB_ELEMS 3 -+#define XYD_Y 65000 -+#define XINDIV_CLOCK 20000000 -+#define UART_BRDL_20M 0x01 -+#define UART_BRDH_20M 0x00 -+ -+static int clock_div_tab[] = { 10, 4, 2}; -+static int clock_div_reg[] = { 4, 2, 1}; -+ -+ -+int en7523_set_uart_baud_rate (struct uart_port *port, unsigned int baud) -+{ -+ struct uart_8250_port *up = up_to_u8250p(port); -+ unsigned int xyd_x, nom, denom; -+ int i; -+ -+ /* set DLAB to access the baud rate divider registers (BRDH, BRDL) */ -+ serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); -+ -+ /* set baud rate calculation defaults */ -+ -+ /* set BRDIV ([BRDH,BRDL]) to 1 */ -+ serial_port_out(port, UART_BRDL, UART_BRDL_20M); -+ serial_port_out(port, UART_BRDH, UART_BRDH_20M); -+ -+ /* calculate XYD_x and XINCLKDR register */ -+ -+ for (i = 0 ; i < CLOCK_DIV_TAB_ELEMS ; i++) { -+ denom = (XINDIV_CLOCK/40) / clock_div_tab[i]; -+ nom = (baud * (XYD_Y/40)); -+ xyd_x = ((nom/denom) << 4); -+ if (xyd_x < XYD_Y) break; -+ } -+ -+ serial_port_out(port, UART_XINCLKDR, clock_div_reg[i]); -+ serial_port_out(port, UART_XYD, (xyd_x<<16) | XYD_Y); -+ -+ /* unset DLAB */ -+ serial_port_out(port, UART_LCR, up->lcr); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(en7523_set_uart_baud_rate); ---- a/drivers/tty/serial/8250/8250_of.c -+++ b/drivers/tty/serial/8250/8250_of.c -@@ -341,6 +341,7 @@ static const struct of_device_id of_plat - { .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, }, - { .compatible = "nuvoton,wpcm450-uart", .data = (void *)PORT_NPCM, }, - { .compatible = "nuvoton,npcm750-uart", .data = (void *)PORT_NPCM, }, -+ { .compatible = "airoha,en7523-uart", .data = (void *)PORT_AIROHA, }, - { /* end of list */ }, - }; - MODULE_DEVICE_TABLE(of, of_platform_serial_table); ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -319,6 +319,14 @@ static const struct serial8250_config ua - .rxtrig_bytes = {1, 8, 16, 30}, - .flags = UART_CAP_FIFO | UART_CAP_AFE, - }, -+ [PORT_AIROHA] = { -+ .name = "Airoha 16550", -+ .fifo_size = 8, -+ .tx_loadsz = 1, -+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, -+ .rxtrig_bytes = {1, 4}, -+ .flags = UART_CAP_FIFO, -+ }, - }; - - /* Uart divisor latch read */ -@@ -2841,6 +2849,12 @@ serial8250_do_set_termios(struct uart_po - - serial8250_set_divisor(port, baud, quot, frac); - -+#ifdef CONFIG_SERIAL_8250_AIROHA -+ /* Airoha SoCs have custom registers for baud rate settings */ -+ if (port->type == PORT_AIROHA) -+ en7523_set_uart_baud_rate(port, baud); -+#endif -+ - /* - * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR - * is written without DLAB set, this mode will be disabled. ---- a/drivers/tty/serial/8250/Kconfig -+++ b/drivers/tty/serial/8250/Kconfig -@@ -355,6 +355,16 @@ config SERIAL_8250_ACORN - system, say Y to this option. The driver can handle 1, 2, or 3 port - cards. If unsure, say N. - -+config SERIAL_8250_AIROHA -+ tristate "Airoha UART support" -+ depends on (ARCH_AIROHA || COMPILE_TEST) && OF && SERIAL_8250 -+ help -+ Selecting this option enables an Airoha SoC specific baud rate -+ calculation routine on an otherwise 16550 compatible UART hardware. -+ -+ If you have an Airoha based board and want to use the serial port, -+ say Y to this option. If unsure, say N. -+ - config SERIAL_8250_BCM2835AUX - tristate "BCM2835 auxiliar mini UART support" - depends on ARCH_BCM2835 || COMPILE_TEST ---- a/drivers/tty/serial/8250/Makefile -+++ b/drivers/tty/serial/8250/Makefile -@@ -20,6 +20,7 @@ obj-$(CONFIG_SERIAL_8250_CONSOLE) += 825 - - obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o - obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o -+obj-$(CONFIG_SERIAL_8250_AIROHA) += 8250_en7523.o - obj-$(CONFIG_SERIAL_8250_ASPEED_VUART) += 8250_aspeed_vuart.o - obj-$(CONFIG_SERIAL_8250_BCM2835AUX) += 8250_bcm2835aux.o - obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o ---- a/include/uapi/linux/serial_reg.h -+++ b/include/uapi/linux/serial_reg.h -@@ -383,5 +383,17 @@ - #define UART_ALTR_EN_TXFIFO_LW 0x01 /* Enable the TX FIFO Low Watermark */ - #define UART_ALTR_TX_LOW 0x41 /* Tx FIFO Low Watermark */ - -+/* -+ * These are definitions for the Airoha EN75XX uart registers -+ * Normalized because of 32 bits registers. -+ */ -+#define UART_BRDL 0 -+#define UART_BRDH 1 -+#define UART_XINCLKDR 10 -+#define UART_XYD 11 -+#define UART_TXLVLCNT 12 -+#define UART_RXLVLCNT 13 -+#define UART_FINTLVL 14 -+ - #endif /* _LINUX_SERIAL_REG_H */ - ---- a/include/uapi/linux/serial_core.h -+++ b/include/uapi/linux/serial_core.h -@@ -31,6 +31,7 @@ - #define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ - #define PORT_RT2880 29 /* Ralink RT2880 internal UART */ - #define PORT_16550A_FSL64 30 /* Freescale 16550 UART with 64 FIFOs */ -+#define PORT_AIROHA 31 /* Airoha 16550 UART */ - - /* - * ARM specific type numbers. These are not currently guaranteed ---- a/include/linux/serial_8250.h -+++ b/include/linux/serial_8250.h -@@ -195,6 +195,7 @@ void serial8250_do_set_mctrl(struct uart - void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, - unsigned int quot); - int fsl8250_handle_irq(struct uart_port *port); -+int en7523_set_uart_baud_rate(struct uart_port *port, unsigned int baud); - int serial8250_handle_irq(struct uart_port *port, unsigned int iir); - u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr); - void serial8250_read_char(struct uart_8250_port *up, u16 lsr); diff --git a/target/linux/airoha/patches-6.12/900-airoha-bmt-support.patch b/target/linux/airoha/patches-6.12/900-airoha-bmt-support.patch deleted file mode 100644 index 5ba31c0829a..00000000000 --- a/target/linux/airoha/patches-6.12/900-airoha-bmt-support.patch +++ /dev/null @@ -1,578 +0,0 @@ ---- /dev/null -+++ b/drivers/mtd/nand/airoha_bmt.c -@@ -0,0 +1,575 @@ -+ -+/* -+ * Airoha BMT algorithm -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "mtk_bmt.h" -+ -+#define MAX_BMT_SIZE (250) -+#define MAX_RAW_BAD_BLOCK_SIZE (250) -+#define POOL_GOOD_BLOCK_PERCENT 8/100 -+#define MAX_BMT_PERCENT 1/8 -+ -+typedef struct { -+ char signature[3]; -+ u8 version; -+ u8 bad_count; // this field is useless -+ u8 size; -+ u8 checksum; -+ u8 reseverd[13]; -+} bmt_table_header; -+ -+typedef struct { -+ u16 from; -+ u16 to; -+} bmt_entry; -+ -+typedef struct { -+ bmt_table_header header; -+ bmt_entry table[MAX_BMT_SIZE]; -+} bmt_table; -+ -+typedef struct { -+ char signature[4]; -+ u32 checksum; -+ u8 version; -+ u8 size; -+ u8 reserved[2]; -+} bbt_table_header; -+ -+typedef struct { -+ bbt_table_header header; -+ u16 table[MAX_RAW_BAD_BLOCK_SIZE]; -+} bbt_table; -+ -+bbt_table bbt; -+bmt_table bmt; -+ -+int bmt_index=0xffff; -+int bbt_index=0xffff; -+unsigned int total_blks , system_blks , bmt_blks, _to, _to2, val; -+ -+module_param(bmt_index, int, S_IRUSR | S_IWUSR); -+module_param(bbt_index, int, S_IRUSR | S_IWUSR); -+module_param(total_blks, int, S_IRUSR | S_IWUSR); -+module_param(system_blks, int, S_IRUSR | S_IWUSR); -+module_param(bmt_blks, int, S_IRUSR | S_IWUSR); -+module_param(_to, int, S_IRUSR | S_IWUSR); -+module_param(_to2, int, S_IRUSR | S_IWUSR); -+module_param(val, int, S_IRUSR | S_IWUSR); -+ -+ -+static bool is_bad_raw(int block) { -+ u8 fdm[4]; -+ int ret; -+ ret = bbt_nand_read(blk_pg(block), bmtd.data_buf, bmtd.pg_size, -+ fdm, sizeof(fdm)); -+ if (ret || fdm[0] != 0xff ){ -+ return true; -+ } -+ return false; -+} -+ -+static bool is_bad( int block) { -+ u8 fdm[4]; -+ int ret; -+ ret = bbt_nand_read(blk_pg(block), bmtd.data_buf, bmtd.pg_size, -+ fdm, sizeof(fdm)); -+ //printk("%x %x %x %x\n", fdm[0], fdm[1], fdm[2], fdm[3]); -+ if (ret || fdm[0] != 0xff || fdm[1] != 0xff ){ -+ return true; -+ } -+ return false; -+} -+ -+ -+static bool is_mapped( int block) { -+ u16 mapped_block; -+ u8 fdm[4]; -+ int ret; -+ -+ ret = bbt_nand_read(blk_pg(block), bmtd.data_buf, bmtd.pg_size, -+ fdm, sizeof(fdm)); -+ mapped_block = (fdm[2] << 8) | fdm[3]; -+ //printk("%u is mapped to %d\n", mapped_block); -+ if (mapped_block == 0xffff) -+ return false; -+ else return true; -+} -+ -+static void mark_bad(int block) { -+ u8 fdm[4] = {0xff, 0xff, 0xff, 0xff}; -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 4, -+ .oobbuf = fdm, -+ .datbuf = NULL, -+ .len = 0, -+ }; -+ int retlen; -+ -+ printk("marking bad :%d\n", block); -+ if (block < system_blks) -+ fdm[0] = 0x00; -+ else fdm[1] = 0x00; -+ -+ retlen = bmtd._write_oob(bmtd.mtd, block << bmtd.blk_shift , &ops) ; -+ if (retlen < 0) { -+ printk("marking bad block failed \n"); -+ } -+} -+ -+ -+static void mark_good(int block) { -+ u8 fdm[4] = {0xff, 0xff, 0xff, 0xff}; -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 4, -+ .oobbuf = fdm, -+ .datbuf = NULL, -+ .len = 0, -+ }; -+ int retlen; -+ retlen = bmtd._write_oob(bmtd.mtd, block << bmtd.blk_shift , &ops) ; -+ if (retlen < 0) { -+ printk("marking bad block failed \n"); -+ } -+} -+ -+static void make_mapping(u16 from , u16 to) { -+ u8 fdm[4] = {0xff, 0xff, 0xff , 0xff}; -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 4, -+ .oobbuf = fdm, -+ .datbuf = NULL, -+ .len = 0, -+ }; -+ int retlen; -+ -+ memcpy(fdm + 2, &to, sizeof(to)); // this has to be exactly like this . -+ retlen = bmtd._write_oob(bmtd.mtd, from << bmtd.blk_shift , &ops) ; -+ if (retlen < 0) { -+ printk("marking bad block failed \n"); -+ } -+} -+ -+static u16 bbt_checksum(void) { -+ int i=0; -+ u16 checksum =0; -+ u8 *data = (u8*) &bbt; -+ checksum += bbt.header.version; -+ checksum += bbt.header.size; -+ data += sizeof(bbt_table_header); -+ for (; i < sizeof(bbt.table); i++) -+ checksum += data[i]; -+ return checksum; -+} -+ -+static bool parse_bbt(void) { -+ int i = system_blks; -+ u8 fdm[4]; -+ for (; i < total_blks; i++) { -+ if( !is_bad(i) -+ && !bbt_nand_read(blk_pg(i),(unsigned char *)&bbt, sizeof(bbt), fdm, sizeof(fdm)) -+ && (strncmp(bbt.header.signature , "RAWB", 4)==0) -+ && (bbt.header.checksum == bbt_checksum()) -+ ) { -+ bbt_index = i; -+ return true; -+ } -+ } -+ return false; -+} -+ -+static u8 bmt_checksum(void) { -+ int i; -+ u8 checksum = 0; -+ u8* data = (u8*)&bmt; -+ checksum += bmt.header.version; -+ checksum += bmt.header.size; -+ data += sizeof(bmt_table_header); -+ for (i=0;i system_blks;i--) { -+ if ( !is_bad(i) -+ && !bbt_nand_read(blk_pg(i),(unsigned char *)&bmt, sizeof(bmt), fdm, sizeof(fdm)) -+ && (strncmp(bmt.header.signature , "BMT", 3)==0) -+ && (bmt.header.checksum == bmt_checksum()) -+ ) { -+ bmt_index = i ; -+ return true; -+ } -+ } -+ return false; -+} -+ -+static void variable_setup(void) { -+ unsigned int need_valid_block_num; -+ int valid_blks = 0; -+ int last_blk; -+ -+ total_blks = bmtd.total_blks; -+ last_blk = total_blks - 1; -+ need_valid_block_num = total_blks * POOL_GOOD_BLOCK_PERCENT; -+ -+ for (; last_blk > 0 ;last_blk--) { -+ if (is_bad_raw(last_blk)) { -+ continue; -+ } -+ valid_blks++; -+ if (valid_blks == need_valid_block_num) { -+ break; -+ } -+ } -+ bmt_blks = total_blks - last_blk; -+ system_blks = total_blks - bmt_blks; -+ bmtd.mtd->size = (total_blks - total_blks * MAX_BMT_PERCENT) * bmtd.mtd->erasesize; -+} -+ -+ -+static int find_available_block(bool start_from_end) { -+ int i=system_blks,d=1; -+ int count = 0; -+ if (start_from_end) -+ i=total_blks-1,d=-1; -+ for (; count < (total_blks - system_blks); count++, i+=d) { -+ if(bmt_index == i || bbt_index == i || is_bad(i) || is_mapped(i)) -+ continue; -+ return i ; -+ } -+ //TODO: handle OOM -+ return -1; -+} -+ -+static void update_bmt_bbt( void ) { -+ int retlen = 0; -+ struct mtd_oob_ops ops , ops1; -+ -+ bbt.header.checksum = bbt_checksum(); -+ bmt.header.checksum = bmt_checksum(); -+ -+ if(bbt_index ==0xffff) bbt_index = find_available_block(false); -+ if(bmt_index ==0xffff) bmt_index = find_available_block(true); -+ -+ bbt_nand_erase(bmt_index); -+ bbt_nand_erase(bbt_index); -+ printk("putting back in bbt_index: %d, bmt_index: %d\n" , bbt_index, bmt_index); -+ -+ ops = (struct mtd_oob_ops) { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 0, -+ .oobbuf = NULL, -+ .len = sizeof(bmt), -+ .datbuf = (u8 *)&bmt, -+ }; -+ -+retry_bmt: -+ retlen = bmtd._write_oob(bmtd.mtd, bmt_index << bmtd.blk_shift, &ops); -+ if (retlen) { -+ printk("error while write"); -+ mark_bad(bmt_index); -+ if (bmt_index > system_blks) { -+ bmt_index--; -+ goto retry_bmt; -+ } -+ return; -+ } -+ ops1 = (struct mtd_oob_ops) { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 0, -+ .oobbuf = NULL, -+ .len = sizeof(bbt), -+ .datbuf = (u8 *)&bbt, -+ }; -+ -+retry_bbt: -+ retlen = bmtd._write_oob(bmtd.mtd, bbt_index << bmtd.blk_shift, &ops1); -+ if (retlen) { -+ printk("error while write"); -+ mark_bad(bbt_index); -+ if (bbt_index < total_blks) { -+ bbt_index++; -+ goto retry_bbt; -+ } -+ return; -+ } -+} -+ -+static bool is_in_bmt(int block) { -+ int i; -+ for (i=0;i= system_blks ;i--) { -+ unsigned short mapped_block; -+ u8 fdm[4]; -+ int ret; -+ -+ if (is_bad(i)) continue; -+ ret = bbt_nand_read(blk_pg(i), bmtd.data_buf, bmtd.pg_size, -+ fdm, sizeof(fdm)); -+ if (ret < 0) -+ mark_bad(i); -+ -+ memcpy(&mapped_block,fdm+2,2); // need to be this way -+ if (mapped_block >= system_blks) continue; -+ printk("block %X was mapped to :%X\n", mapped_block, i); -+ bmt.table[bmt.header.size++] = (bmt_entry){.from = mapped_block , .to = i}; -+ } -+ memset(&bbt,0x00,sizeof(bbt)); -+ memcpy(&bbt.header.signature , "RAWB", 4); -+ bbt.header.version = 1; -+ bbt.header.size = 0; -+ for ( i = 0 ; i < system_blks; i++) { -+ if (is_bad_raw(i) && !is_in_bmt(i)) -+ bbt.table[bbt.header.size++] = (u16)i; -+ } -+ bmt.header.checksum = bmt_checksum(); -+ bbt.header.checksum = bbt_checksum(); -+ update_bmt_bbt(); -+ printk("bbt and bmt reconstructed successfully\n"); -+} -+ -+ -+static bool remap_block(u16 block , u16 mapped_block, int copy_len) { -+ bool mapped_already_in_bbt = false; -+ bool mapped_already_in_bmt = false; -+ bool block_already_in_bbt = false; -+ u16 new_block = find_available_block(false); -+ int i; -+ // TODO check for -1 -+ -+ bbt_nand_erase(new_block); -+ if (copy_len) -+ bbt_nand_copy(new_block , mapped_block , copy_len); -+ -+ for (i=0; i < bmt.header.size; i++) -+ if (bmt.table[i].from == block) { -+ bmt.table[i].to = new_block; -+ mapped_already_in_bmt = true; -+ break; -+ } -+ -+ if (!mapped_already_in_bmt) -+ bmt.table[bmt.header.size++] = (bmt_entry){ .from = block, .to = new_block}; -+ -+ for (i=0;i system_blks) -+ return block; -+ for (i = 0; i < bmt.header.size; i++) -+ if (bmt.table[i].from == block) -+ return bmt.table[i].to; -+ return block; -+} -+ -+static void unmap_block( u16 block) { // not required -+ printk("unmapping is called on block : %d\n", block); -+} -+ -+ -+static int debug( void* data , u64 cmd) { -+ int i; -+ printk("val: %d\n", val); -+ printk("_to: %d\n", _to); -+ if (val == 0 ) { -+ printk("fixing all\n"); -+ for (i=0;ierasesize); -+ mapped_block = get_mapping_block(_to); -+ printk("after mapped to: %d\n", mapped_block); -+ } else if(val ==2 ) { -+ printk("bmt table: \n"); -+ for (i = 0 ; i < bmt.header.size;i++) { -+ printk("%d->%d\n", bmt.table[i].from , bmt.table[i].to); -+ } -+ printk("bbt table\n"); -+ for (i =0;i< bbt.header.size;i++) { -+ printk("%d ", bbt.table[i]); -+ } -+ printk("\n"); -+ } else if(val == 3) { -+ printk("reconstruct from oob\n"); -+ reconstruct_from_oob(); -+ } else if (val == 4) { -+ printk("showing the oobreconstruct_from_oob of %d\n", _to); -+ printk("%d\n",is_bad(_to)); -+ } else if (val == 5 ) { -+ printk("trying to parse_bmt again %d\n", parse_bmt()); -+ } else if (val == 6 ) { -+ printk("marking bad : %d", _to); -+ mark_bad(_to); -+ } else if ( val == 7) { -+ struct mtd_oob_ops opsk = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 0, -+ .oobbuf = NULL, -+ .len = sizeof(bmt), -+ .datbuf = (u8 *)&bmt, -+ }; -+ int retlen; -+ printk("parse bmt from the %d block \n", _to); -+ retlen = bmtd._read_oob(bmtd.mtd, _to << bmtd.blk_shift , &opsk); -+ -+ printk("status : %d\n", retlen); -+ } else if (val == 8) { -+ u8 *data; -+ int j; -+ printk("dump bmt hex\n"); -+ data = (u8 *)&bmt; -+ for (j =0;j < 50;j++) { -+ if(j%20==0) printk("\n"); -+ printk("%X ", data[j]); -+ } -+ printk("bbt table\n"); -+ data = (u8 *)&bbt; -+ for (j =0;j < 50;j++) { -+ if(j%20==0) printk("\n"); -+ printk("%X ", data[j]); -+ } -+ } else if (val == 9) { -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 0, -+ .oobbuf = NULL, -+ .len = sizeof(bmt), -+ .datbuf = (u8 *)&bmt, -+ }; -+ int retlen; -+ printk("put bmt at index\n"); -+ retlen = bmtd._write_oob(bmtd.mtd, _to << bmtd.blk_shift, &ops); -+ bmt.header.checksum = bmt_checksum(); -+ if (retlen < 0) { -+ printk("error while write"); -+ } -+ } else if (val == 10) { -+ printk("erase block %d\n", _to); -+ bbt_nand_erase(_to); -+ } else if (val == 11) { -+ char *buf1, *buf2; -+ struct mtd_oob_ops ops = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 0, -+ .oobbuf = NULL, -+ }; -+ struct mtd_oob_ops ops1 = { -+ .mode = MTD_OPS_PLACE_OOB, -+ .ooboffs = 0, -+ .ooblen = 0, -+ .oobbuf = NULL, -+ }; -+ int retlen; -+ int j; -+ -+ printk("tranfering content from block :%d to %d\n", _to , _to2); -+ bbt_nand_copy(_to2, _to, bmtd.mtd->erasesize); -+ printk("now we check size\n"); -+ -+ buf1 = (char*) kzalloc(sizeof(char) * bmtd.mtd->erasesize , GFP_KERNEL); -+ buf2 = (char*) kzalloc(sizeof(char) * bmtd.mtd->erasesize , GFP_KERNEL); -+ -+ ops.len = sizeof(char) * bmtd.mtd->erasesize; -+ ops.datbuf = buf1; -+ retlen = bmtd._read_oob(bmtd.mtd, _to << bmtd.blk_shift, &ops); -+ if (retlen < 0) { -+ printk("error while write\n"); -+ } -+ -+ ops1.len = sizeof(char) * bmtd.mtd->erasesize; -+ ops1.datbuf = buf2; -+ retlen = bmtd._read_oob(bmtd.mtd, _to << bmtd.blk_shift, &ops1); -+ if (retlen < 0) { -+ printk("error while write"); -+ } -+ for (j = 0 ; j < bmtd.mtd->erasesize ;j++) { -+ if (j%20==0) { -+ printk("\n"); -+ } -+ printk("%X %X ", buf1[j], buf2[j]); -+ } -+ printk("\n"); -+ -+ } -+ return 0; -+} -+ -+ -+const struct mtk_bmt_ops airoha_bmt_ops = { -+ .sig = "bmt", -+ .sig_len = 3, -+ .init = init, -+ .remap_block = remap_block, -+ .unmap_block = unmap_block, -+ .get_mapping_block = get_mapping_block, -+ .debug = debug, -+}; diff --git a/target/linux/airoha/patches-6.12/901-snand-mtk-bmt-support.patch b/target/linux/airoha/patches-6.12/901-snand-mtk-bmt-support.patch deleted file mode 100644 index 2dc81292ec4..00000000000 --- a/target/linux/airoha/patches-6.12/901-snand-mtk-bmt-support.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) - { -@@ -1604,6 +1605,7 @@ static int spinand_probe(struct spi_mem - if (ret) - return ret; - -+ mtk_bmt_attach(mtd); - ret = mtd_device_register(mtd, NULL, 0); - if (ret) - goto err_spinand_cleanup; -@@ -1611,6 +1613,7 @@ static int spinand_probe(struct spi_mem - return 0; - - err_spinand_cleanup: -+ mtk_bmt_detach(mtd); - spinand_cleanup(spinand); - - return ret; -@@ -1629,6 +1632,7 @@ static int spinand_remove(struct spi_mem - if (ret) - return ret; - -+ mtk_bmt_detach(mtd); - spinand_cleanup(spinand); - - return 0; diff --git a/target/linux/airoha/patches-6.12/911-clk-en7581-Separate-PERST-from-refclk-in-PCIe-clock.patch b/target/linux/airoha/patches-6.12/911-clk-en7581-Separate-PERST-from-refclk-in-PCIe-clock.patch deleted file mode 100644 index 9469c1c5ba2..00000000000 --- a/target/linux/airoha/patches-6.12/911-clk-en7581-Separate-PERST-from-refclk-in-PCIe-clock.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Ryan Chen -Subject: clk: en7581: Separate PERST from refclk in PCIe clock callbacks - -The EN7581 PCIe clock enable/disable callbacks currently toggle both -PERST (reset) and reference clock signals together. This prevents the -PCIe controller driver from properly sequencing PERST relative to MAC -register configuration, which is required for x2 link mode. - -Separate the two concerns: clock callbacks only manage reference clocks -(REFCLK_EN0/EN1), while PERST (PERSTOUT/PERSTOUT1/PERSTOUT2) is left -to the PCIe controller driver to manage directly via the NP_SCU regmap. - -Signed-off-by: Ryan Chen ---- a/drivers/clk/clk-en7523.c -+++ b/drivers/clk/clk-en7523.c -@@ -960,9 +960,11 @@ static int en7581_pci_enable(struct clk_ - struct regmap *map = cg->map; - u32 mask; - -- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | -- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | -- REG_PCI_CONTROL_PERSTOUT; -+ /* Only enable reference clocks - PERST is managed separately by the -+ * PCIe controller driver to allow proper sequencing of MAC register -+ * configuration between PERST assert and deassert. -+ */ -+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; - regmap_set_bits(map, REG_PCI_CONTROL, mask); - - return 0; -@@ -974,9 +976,8 @@ static void en7581_pci_disable(struct cl - struct regmap *map = cg->map; - u32 mask; - -- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 | -- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 | -- REG_PCI_CONTROL_PERSTOUT; -+ /* Only disable reference clocks - PCIe driver manages PERST */ -+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1; - regmap_clear_bits(map, REG_PCI_CONTROL, mask); - usleep_range(1000, 2000); - } diff --git a/target/linux/airoha/patches-6.12/912-pcie-mediatek-gen3-Add-x2-link-support-for-Airoha-EN7581.patch b/target/linux/airoha/patches-6.12/912-pcie-mediatek-gen3-Add-x2-link-support-for-Airoha-EN7581.patch deleted file mode 100644 index 94267562036..00000000000 --- a/target/linux/airoha/patches-6.12/912-pcie-mediatek-gen3-Add-x2-link-support-for-Airoha-EN7581.patch +++ /dev/null @@ -1,244 +0,0 @@ -From: Ryan Chen -Subject: PCI: mediatek-gen3: Add PCIe x2 link support for Airoha EN7581 - -The Airoha EN7581 SoC supports PCIe x2 mode where two PCIe lanes are -bonded together for a single x2 link. This requires coordination with -the NP_SCU system controller for serdes mux routing, PERST management, -and lane configuration. - -The x2 initialization sequence: -1. Assert serdes reset and PERST before enabling clocks -2. Configure serdes mux for 2-lane mode -3. Enable reference clocks, deassert serdes reset -4. Clear x1 mode bit and write EQ presets on both MACs -5. Deassert PERST to start link training - -After initial link training, if the link negotiates Gen2 instead of -Gen3, a serdes reset toggle forces the MAC to re-discover the PHY -Gen3 capability from the Link Capabilities 2 register, allowing the -link to retrain at Gen3 x2 (8 GT/s). - -Signed-off-by: Ryan Chen ---- a/drivers/pci/controller/pcie-mediatek-gen3.c -+++ b/drivers/pci/controller/pcie-mediatek-gen3.c -@@ -61,6 +61,14 @@ - #define PCIE_LTSSM_STATE(val) ((val & PCIE_LTSSM_STATE_MASK) >> 24) - #define PCIE_LTSSM_STATE_L2_IDLE 0x14 - -+/* EN7581 x2 mode support */ -+#define PCIE_SETTING_REG_X1_MODE BIT(13) -+ -+/* EN7581 NP_SCU register offsets for x2 link init */ -+#define NP_SCU_LANE_CFG0 0x830 -+#define NP_SCU_LANE_CFG1 0x834 -+#define NP_SCU_CTRL_REG 0x88 -+ - #define PCIE_LINK_STATUS_REG 0x154 - #define PCIE_PORT_LINKUP BIT(8) - -@@ -205,6 +213,11 @@ struct mtk_gen3_pcie { - DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM); - - const struct mtk_gen3_pcie_pdata *soc; -+ -+ /* EN7581 x2 mode support */ -+ struct regmap *np_scu; -+ bool x2_mode; -+ void __iomem *sister_base; - }; - - /* LTSSM state in PCIE_LTSSM_STATUS_REG bit[28:24] */ -@@ -925,6 +938,28 @@ static int mtk_pcie_en7581_power_up(stru - size = lower_32_bits(resource_size(entry->res)); - regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size))); - -+ /* Lookup NP_SCU regmap for x2 mode support */ -+ pcie->np_scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,np-scu"); -+ if (IS_ERR(pcie->np_scu)) { -+ dev_dbg(dev, "np_scu not available, x2 mode disabled\n"); -+ pcie->np_scu = NULL; -+ } -+ -+ /* Check for x2 mode property */ -+ pcie->x2_mode = of_property_read_bool(dev->of_node, "airoha,x2-mode"); -+ if (pcie->x2_mode) -+ dev_info(dev, "x2 mode enabled\n"); -+ -+ /* Map sister MAC for x2 mode (MAC1 at +0x20000) */ -+ if (pcie->x2_mode) { -+ pcie->sister_base = devm_ioremap(dev, -+ pcie->reg_base + 0x20000, 0x20000); -+ if (!pcie->sister_base) -+ dev_warn(dev, "failed to map sister MAC for x2\n"); -+ else -+ dev_info(dev, "x2 mode: sister MAC mapped\n"); -+ } -+ - err = phy_set_mode(pcie->phy, PHY_MODE_PCIE); - if (err) { - dev_err(dev, "failed to set PHY mode\n"); -@@ -962,17 +997,28 @@ static int mtk_pcie_en7581_power_up(stru - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - -- val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | -- FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | -- FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | -- FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); -- writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG); -- -- val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | -- FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | -- FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | -- FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); -- writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); -+ /* -+ * EN7581 x2: Assert PERST and serdes reset before enabling clocks -+ * so that MAC registers can be configured while devices are held -+ * in reset, ensuring link trains with the correct x2 settings. -+ */ -+ if (pcie->x2_mode && pcie->np_scu) { -+ /* Assert serdes reset on all lanes */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), BIT(26) | BIT(27)); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(27), BIT(27)); -+ msleep(100); -+ -+ /* Assert PERST on all ports */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(16) | BIT(26) | BIT(29), 0); -+ -+ /* Set serdes mux for 2-lane mode (bits[1:0] = 2) */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(0) | BIT(1), BIT(1)); -+ mdelay(1); -+ } - - err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks); - if (err) { -@@ -981,12 +1027,121 @@ static int mtk_pcie_en7581_power_up(stru - } - - /* -- * Airoha EN7581 performs PCIe reset via clk callbacks since it has a -- * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to -- * complete the PCIe reset. -+ * Airoha EN7581: clock enable only provides refclk (patch 911). -+ * For x2, PERST + serdes are already asserted above. -+ * Wait for refclk to stabilize. - */ - msleep(PCIE_T_PVPERL_MS); - -+ if (pcie->x2_mode && pcie->np_scu) { -+ /* -+ * EN7581 x2: PERST asserted, serdes reset asserted, -+ * refclk now stable. Complete the init sequence. -+ */ -+ msleep(30); -+ -+ /* Deassert serdes reset on all lanes */ -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), 0); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(27), 0); -+ -+ /* Clear SETTING_REG bit 13 for x2 mode on both MACs */ -+ val = readl_relaxed(pcie->base + PCIE_SETTING_REG); -+ writel_relaxed(val & ~PCIE_SETTING_REG_X1_MODE, -+ pcie->base + PCIE_SETTING_REG); -+ if (pcie->sister_base) { -+ val = readl_relaxed(pcie->sister_base + 0x80); -+ writel_relaxed(val & ~PCIE_SETTING_REG_X1_MODE, -+ pcie->sister_base + 0x80); -+ } -+ -+ /* EQ presets on both MACs */ -+ writel_relaxed(0x41474147, pcie->base + PCIE_EQ_PRESET_01_REG); -+ if (pcie->sister_base) -+ writel_relaxed(0x41474147, pcie->sister_base + 0x100); -+ writel_relaxed(0x1018020f, pcie->base + PCIE_PIPE4_PIE8_REG); -+ if (pcie->sister_base) -+ writel_relaxed(0x1018020f, pcie->sister_base + 0x338); -+ -+ /* Deassert PERST for all ports - link training starts */ -+ msleep(10); -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(16) | BIT(26) | BIT(29), -+ BIT(16) | BIT(26) | BIT(29)); -+ -+ /* Wait for link training to complete */ -+ msleep(800); -+ -+ /* -+ * Check if link trained at Gen3. If not, toggle serdes -+ * reset to force MAC to re-discover PHY Gen3 capability. -+ * Without this, MAC only advertises Gen1-Gen2 in LnkCap2. -+ */ -+ val = readl_relaxed(pcie->base + PCIE_LINK_STATUS_REG); -+ if (val & PCIE_PORT_LINKUP) { -+ void __iomem *cfg = pcie->base + PCIE_CFG_OFFSET_ADDR; -+ u8 cap_ptr; -+ int speed = 0; -+ -+ /* Walk PCI cap list to find PCIe cap (ID=0x10) */ -+ cap_ptr = readl_relaxed(cfg + PCI_CAPABILITY_LIST) & 0xFF; -+ while (cap_ptr >= 0x40) { -+ u32 hdr = readl_relaxed(cfg + cap_ptr); -+ if ((hdr & 0xFF) == PCI_CAP_ID_EXP) { -+ u32 lnk = readl_relaxed(cfg + cap_ptr + PCI_EXP_LNKCTL); -+ speed = (lnk >> 16) & PCI_EXP_LNKSTA_CLS; -+ break; -+ } -+ cap_ptr = (hdr >> 8) & 0xFF; -+ } -+ -+ if (speed > 0 && speed < 3) { -+ dev_info(dev, "x2: link at Gen%d, toggling serdes for Gen3\n", speed); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(7) | BIT(8), BIT(7) | BIT(8)); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), BIT(26) | BIT(27)); -+ msleep(1000); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG0, -+ BIT(7) | BIT(8), 0); -+ regmap_update_bits(pcie->np_scu, NP_SCU_LANE_CFG1, -+ BIT(26) | BIT(27), 0); -+ msleep(2000); -+ dev_info(dev, "x2: serdes toggle done, link retraining\n"); -+ } else { -+ dev_info(dev, "x2: link at Gen%d, no toggle needed\n", speed); -+ } -+ } else { -+ dev_info(dev, "x2: link not up after init, skipping speed check\n"); -+ } -+ -+ dev_info(dev, "x2: init complete, PERST deasserted\n"); -+ } else { -+ /* -+ * Non-x2 mode: standard EQ config then deassert PERST. -+ */ -+ val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) | -+ FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) | -+ FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) | -+ FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41); -+ writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG); -+ -+ val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT | -+ FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) | -+ FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) | -+ FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf); -+ writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG); -+ -+ /* Deassert PERST for all ports */ -+ if (pcie->np_scu) { -+ regmap_update_bits(pcie->np_scu, NP_SCU_CTRL_REG, -+ BIT(16) | BIT(26) | BIT(29), -+ BIT(16) | BIT(26) | BIT(29)); -+ msleep(100); -+ } -+ } -+ - return 0; - - err_clk_prepare_enable: diff --git a/target/linux/airoha/patches-6.12/915-01-net-netfilter-flowtable-Add-the-capability-to-offloa.patch b/target/linux/airoha/patches-6.12/915-01-net-netfilter-flowtable-Add-the-capability-to-offloa.patch deleted file mode 100644 index e11d368888c..00000000000 --- a/target/linux/airoha/patches-6.12/915-01-net-netfilter-flowtable-Add-the-capability-to-offloa.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 6408cdca652b1f85e5b8582c283203d11f4dedcb Mon Sep 17 00:00:00 2001 -Message-ID: <6408cdca652b1f85e5b8582c283203d11f4dedcb.1779086987.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Sun, 17 May 2026 21:11:27 +0200 -Subject: [PATCH net-next 1/2] net: netfilter: flowtable: Add the capability to - offload dscp field - -Introduce the capability to hw offload via netfilter flowtable APIs the -IP TOS info. Implement the sw offloading for DSCP field via the -netfilter flowtable APIs. - -Signed-off-by: Lorenzo Bianconi ---- - include/net/netfilter/nf_flow_table.h | 2 ++ - net/netfilter/nf_flow_table_ip.c | 12 ++++++++++++ - net/netfilter/nf_flow_table_offload.c | 5 +++++ - net/netfilter/nft_flow_offload.c | 22 ++++++++++++++++++++++ - 4 files changed, 41 insertions(+) - ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -29,6 +29,7 @@ struct nf_flow_key { - struct flow_dissector_key_ipv4_addrs ipv4; - struct flow_dissector_key_ipv6_addrs ipv6; - }; -+ struct flow_dissector_key_ip ip; - struct flow_dissector_key_keyid enc_key_id; - union { - struct flow_dissector_key_ipv4_addrs enc_ipv4; -@@ -138,6 +139,7 @@ struct flow_offload_tuple { - encap_num:2, - in_vlan_ingress:2; - u16 mtu; -+ u8 dscp; - union { - struct { - struct dst_entry *dst_cache; ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -372,6 +372,7 @@ static int nf_flow_offload_forward(struc - struct flow_offload *flow; - unsigned int thoff, mtu; - struct iphdr *iph; -+ u8 dscp; - - dir = tuplehash->tuple.dir; - flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -@@ -401,6 +402,12 @@ static int nf_flow_offload_forward(struc - iph = ip_hdr(skb); - nf_flow_nat_ip(flow, skb, thoff, dir, iph); - -+ dscp = FIELD_GET(INET_DSCP_MASK, ipv4_get_dsfield(iph)); -+ if (tuplehash->tuple.dscp != dscp) -+ ipv4_change_dsfield(iph, INET_ECN_MASK, -+ FIELD_PREP(INET_DSCP_MASK, -+ tuplehash->tuple.dscp)); -+ - ip_decrease_ttl(iph); - skb_clear_tstamp(skb); - -@@ -651,6 +658,7 @@ static int nf_flow_offload_ipv6_forward( - struct flow_offload *flow; - unsigned int thoff, mtu; - struct ipv6hdr *ip6h; -+ u8 dscp; - - dir = tuplehash->tuple.dir; - flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); -@@ -679,6 +687,12 @@ static int nf_flow_offload_ipv6_forward( - ip6h = ipv6_hdr(skb); - nf_flow_nat_ipv6(flow, skb, dir, ip6h); - -+ dscp = FIELD_GET(INET_DSCP_MASK, ipv6_get_dsfield(ip6h)); -+ if (tuplehash->tuple.dscp != dscp) -+ ipv6_change_dsfield(ip6h, INET_ECN_MASK, -+ FIELD_PREP(INET_DSCP_MASK, -+ tuplehash->tuple.dscp)); -+ - ip6h->hop_limit--; - skb_clear_tstamp(skb); - ---- a/net/netfilter/nf_flow_table_offload.c -+++ b/net/netfilter/nf_flow_table_offload.c -@@ -103,6 +103,7 @@ static int nf_flow_rule_match(struct nf_ - NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_BASIC, basic); - NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4); - NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6); -+ NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_IP, ip); - NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_TCP, tcp); - NF_FLOW_DISSECTOR(match, FLOW_DISSECTOR_KEY_PORTS, tp); - -@@ -168,6 +169,10 @@ static int nf_flow_rule_match(struct nf_ - match->dissector.used_keys |= BIT_ULL(key->control.addr_type); - mask->basic.n_proto = 0xffff; - -+ key->ip.tos = FIELD_PREP(INET_DSCP_MASK, tuple->dscp); -+ mask->ip.tos = 0xff; -+ match->dissector.used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_IP); -+ - switch (tuple->l4proto) { - case IPPROTO_TCP: - key->tcp.flags = 0; ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include /* for ipv4 options. */ - #include - #include -@@ -279,6 +280,27 @@ static int nft_flow_route(const struct n - return 0; - } - -+static void nft_flow_set_dscp(const struct nft_pktinfo *pkt, -+ struct flow_offload *flow, -+ enum ip_conntrack_dir dir) -+{ -+ struct flow_offload_tuple *tuple = &flow->tuplehash[dir].tuple; -+ struct sk_buff *skb = pkt->skb; -+ -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+ tuple->dscp = FIELD_GET(INET_DSCP_MASK, -+ ipv4_get_dsfield(ip_hdr(skb))); -+ break; -+ case htons(ETH_P_IPV6): -+ tuple->dscp = FIELD_GET(INET_DSCP_MASK, -+ ipv6_get_dsfield(ipv6_hdr(skb))); -+ break; -+ default: -+ break; -+ } -+} -+ - static bool nft_flow_offload_skip(struct sk_buff *skb, int family) - { - if (skb_sec_path(skb)) -@@ -371,6 +393,9 @@ static void nft_flow_offload_eval(const - if (!flow) - goto err_flow_alloc; - -+ nft_flow_set_dscp(pkt, flow, dir); -+ nft_flow_set_dscp(pkt, flow, !dir); -+ - flow_offload_route_init(flow, &route); - if (tcph) - flow_offload_ct_tcp(ct); diff --git a/target/linux/airoha/patches-6.12/915-02-net-airoha-Set-hw-QoS-parameter-according-to-the-pac.patch b/target/linux/airoha/patches-6.12/915-02-net-airoha-Set-hw-QoS-parameter-according-to-the-pac.patch deleted file mode 100644 index 15eded87d32..00000000000 --- a/target/linux/airoha/patches-6.12/915-02-net-airoha-Set-hw-QoS-parameter-according-to-the-pac.patch +++ /dev/null @@ -1,94 +0,0 @@ -From b9870ade9498f4119d3f8f8368fcd13e1fa0c7c9 Mon Sep 17 00:00:00 2001 -Message-ID: -In-Reply-To: <6408cdca652b1f85e5b8582c283203d11f4dedcb.1779086987.git.lorenzo@kernel.org> -References: <6408cdca652b1f85e5b8582c283203d11f4dedcb.1779086987.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Mon, 18 May 2026 08:36:20 +0200 -Subject: [PATCH net-next 2/2] net: airoha: Set hw QoS parameter according to - the packet dscp - -Introduce the capability to hw offload via netfilter flowtable APIs the -IP TOS info in order to configure hw queue and dscp field. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_ppe.c | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - - #include "airoha_regs.h" - #include "airoha_eth.h" -@@ -298,7 +299,7 @@ static int airoha_ppe_foe_entry_prepare( - struct airoha_foe_entry *hwe, - struct net_device *dev, int type, - struct airoha_flow_data *data, -- int l4proto) -+ int l4proto, u8 dsfield) - { - u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val; - int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev); -@@ -331,7 +332,7 @@ static int airoha_ppe_foe_entry_prepare( - info.wcid); - } else { - struct airoha_gdm_port *port = netdev_priv(dev); -- u8 pse_port, channel; -+ u8 pse_port, channel, priority; - - if (!airoha_is_valid_gdm_port(eth, port)) - return -EINVAL; -@@ -350,9 +351,13 @@ static int airoha_ppe_foe_entry_prepare( - */ - channel = dsa_port >= 0 ? dsa_port : port->id; - channel = channel % AIROHA_NUM_QOS_CHANNELS; -- qdata |= FIELD_PREP(AIROHA_FOE_CHANNEL, channel); -+ priority = rt_tos2priority(dsfield); -+ priority = priority % AIROHA_NUM_QOS_QUEUES; -+ qdata |= FIELD_PREP(AIROHA_FOE_CHANNEL, channel) | -+ FIELD_PREP(AIROHA_FOE_QID, priority); - - val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port) | -+ FIELD_PREP(AIROHA_FOE_IB2_DSCP, dsfield) | - AIROHA_FOE_IB2_PSE_QOS; - /* For downlink traffic consume SRAM memory for hw - * forwarding descriptors queue. -@@ -1044,9 +1049,9 @@ static int airoha_ppe_flow_offload_repla - struct net_device *odev = NULL; - struct flow_action_entry *act; - struct airoha_foe_entry hwe; -+ u8 dsfield = 0, l4proto = 0; - int err, i, offload_type; - u16 addr_type = 0; -- u8 l4proto = 0; - - if (rhashtable_lookup(ð->flow_table, &f->cookie, - airoha_flow_table_params)) -@@ -1076,6 +1081,13 @@ static int airoha_ppe_flow_offload_repla - return -EOPNOTSUPP; - } - -+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { -+ struct flow_match_ip match; -+ -+ flow_rule_match_ip(rule, &match); -+ dsfield = match.key->tos; -+ } -+ - switch (addr_type) { - case 0: - offload_type = PPE_PKT_TYPE_BRIDGE; -@@ -1141,7 +1153,7 @@ static int airoha_ppe_flow_offload_repla - return -EINVAL; - - err = airoha_ppe_foe_entry_prepare(eth, &hwe, odev, offload_type, -- &data, l4proto); -+ &data, l4proto, dsfield); - if (err) - return err; - diff --git a/target/linux/airoha/patches-6.12/916-net-airoha-Implement-LRO-TCP-support.patch b/target/linux/airoha/patches-6.12/916-net-airoha-Implement-LRO-TCP-support.patch deleted file mode 100644 index 7636ecbbc82..00000000000 --- a/target/linux/airoha/patches-6.12/916-net-airoha-Implement-LRO-TCP-support.patch +++ /dev/null @@ -1,392 +0,0 @@ -From 598e1ddfe85ad0f4778eeadd5d878209dd931280 Mon Sep 17 00:00:00 2001 -Message-ID: <598e1ddfe85ad0f4778eeadd5d878209dd931280.1779112628.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Thu, 14 May 2026 20:25:19 +0200 -Subject: [PATCH] net: airoha: Implement LRO TCP support - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 178 ++++++++++++++++++++-- - drivers/net/ethernet/airoha/airoha_eth.h | 23 +++ - drivers/net/ethernet/airoha/airoha_regs.h | 22 ++- - 3 files changed, 208 insertions(+), 15 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - - #include "airoha_regs.h" -@@ -439,6 +440,48 @@ static void airoha_fe_crsn_qsel_init(str - CDM_CRSN_QSEL_Q1)); - } - -+static void airoha_fe_lro_init_rx_queue(struct airoha_eth *eth, int qdma_id, -+ int lro_queue_index, int qid, -+ int buf_size) -+{ -+ int id = qdma_id + 1; -+ -+ airoha_fe_rmw(eth, REG_CDM_LRO_LIMIT(id), -+ CDM_LRO_AGG_NUM_MASK | CDM_LRO_AGG_SIZE_MASK, -+ FIELD_PREP(CDM_LRO_AGG_SIZE_MASK, buf_size) | -+ FIELD_PREP(CDM_LRO_AGG_NUM_MASK, -+ AIROHA_RXQ_LRO_MAX_AGG_COUNT)); -+ airoha_fe_rmw(eth, REG_CDM_LRO_AGE_TIME(id), -+ CDM_LRO_AGE_TIME_MASK | CDM_LRO_AGG_TIME_MASK, -+ FIELD_PREP(CDM_LRO_AGE_TIME_MASK, -+ AIROHA_RXQ_LRO_MAX_AGE_TIME) | -+ FIELD_PREP(CDM_LRO_AGG_TIME_MASK, -+ AIROHA_RXQ_LRO_MAX_AGG_TIME)); -+ airoha_fe_rmw(eth, REG_CDM_LRO_RXQ(id, lro_queue_index), -+ LRO_RXQ_MASK(lro_queue_index), -+ __field_prep(LRO_RXQ_MASK(lro_queue_index), qid)); -+ airoha_fe_set(eth, REG_CDM_LRO_EN(id), BIT(lro_queue_index)); -+} -+ -+static void airoha_fe_lro_disable(struct airoha_eth *eth, int qdma_id) -+{ -+ int i, id = qdma_id + 1; -+ -+ airoha_fe_clear(eth, REG_CDM_LRO_EN(id), LRO_RXQ_EN_MASK); -+ airoha_fe_clear(eth, REG_CDM_LRO_LIMIT(id), -+ CDM_LRO_AGG_NUM_MASK | CDM_LRO_AGG_SIZE_MASK); -+ airoha_fe_clear(eth, REG_CDM_LRO_AGE_TIME(id), -+ CDM_LRO_AGE_TIME_MASK | CDM_LRO_AGG_TIME_MASK); -+ for (i = 0; i < AIROHA_MAX_NUM_LRO_QUEUES; i++) -+ airoha_fe_clear(eth, REG_CDM_LRO_RXQ(id, i), LRO_RXQ_MASK(i)); -+} -+ -+static bool airoha_fe_lro_is_enabled(struct airoha_eth *eth, int qdma_id) -+{ -+ return airoha_fe_get(eth, REG_CDM_LRO_EN(qdma_id + 1), -+ LRO_RXQ_EN_MASK); -+} -+ - static int airoha_fe_init(struct airoha_eth *eth) - { - airoha_fe_maccr_init(eth); -@@ -603,6 +646,85 @@ static int airoha_qdma_get_gdm_port(stru - return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; - } - -+static int airoha_qdma_lro_rx_process(struct airoha_queue *q, -+ struct airoha_qdma_desc *desc) -+{ -+ u32 desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl)); -+ u32 msg1 = le32_to_cpu(READ_ONCE(desc->msg1)); -+ u32 msg2 = le32_to_cpu(READ_ONCE(desc->msg2)); -+ u32 msg3 = le32_to_cpu(READ_ONCE(desc->msg3)); -+ struct sk_buff *skb = q->skb; -+ u32 len, th_off, tcp_ack_seq; -+ u16 tcp_win, l2_len; -+ struct tcphdr *th; -+ bool ipv4, ipv6; -+ -+ if (FIELD_GET(QDMA_ETH_RXMSG_AGG_COUNT_MASK, msg2) <= 1) -+ return 0; -+ -+ ipv4 = FIELD_GET(QDMA_ETH_RXMSG_IP4_MASK, msg1); -+ ipv6 = FIELD_GET(QDMA_ETH_RXMSG_IP6_MASK, msg1); -+ if (!ipv4 && !ipv6) -+ return -EOPNOTSUPP; -+ -+ l2_len = FIELD_GET(QDMA_ETH_RXMSG_L2_LEN_MASK, msg2); -+ len = FIELD_GET(QDMA_DESC_LEN_MASK, desc_ctrl); -+ if (ipv4) { -+ struct iphdr *iph; -+ -+ if (!pskb_may_pull(skb, l2_len + sizeof(*iph))) -+ return -EINVAL; -+ -+ iph = (struct iphdr *)(skb->data + l2_len); -+ if (iph->protocol != IPPROTO_TCP) -+ return -EOPNOTSUPP; -+ -+ iph->tot_len = cpu_to_be16(len - l2_len); -+ iph->check = 0; -+ iph->check = ip_fast_csum((void *)iph, iph->ihl); -+ th_off = l2_len + (iph->ihl << 2); -+ } else { -+ struct ipv6hdr *ip6h; -+ -+ if (!pskb_may_pull(skb, l2_len + sizeof(*ip6h))) -+ return -EINVAL; -+ -+ ip6h = (struct ipv6hdr *)(skb->data + l2_len); -+ if (ip6h->nexthdr != NEXTHDR_TCP) -+ return -EOPNOTSUPP; -+ -+ ip6h->payload_len = cpu_to_be16(len - l2_len - sizeof(*ip6h)); -+ th_off = l2_len + sizeof(*ip6h); -+ } -+ -+ tcp_win = FIELD_GET(QDMA_ETH_RXMSG_TCP_WIN_MASK, msg3); -+ tcp_ack_seq = le32_to_cpu(READ_ONCE(desc->data)); -+ -+ if (!pskb_may_pull(skb, th_off + sizeof(*th))) -+ return -EINVAL; -+ -+ th = (struct tcphdr *)(skb->data + th_off); -+ th->ack_seq = cpu_to_be32(tcp_ack_seq); -+ th->window = cpu_to_be16(tcp_win); -+ -+ /* Check tcp timestamp option */ -+ if (th->doff == (sizeof(*th) + TCPOLEN_TSTAMP_ALIGNED) / 4) { -+ __be32 *topt = (__be32 *)(th + 1); -+ -+ if (*topt == cpu_to_be32((TCPOPT_NOP << 24) | -+ (TCPOPT_NOP << 16) | -+ (TCPOPT_TIMESTAMP << 8) | -+ TCPOLEN_TIMESTAMP)) { -+ __le32 tcp_ts_reply = READ_ONCE(desc->tcp_ts_reply); -+ -+ put_unaligned_be32(le32_to_cpu(tcp_ts_reply), -+ topt + 2); -+ } -+ } -+ -+ return 0; -+} -+ - static int airoha_qdma_rx_process(struct airoha_queue *q, int budget) - { - enum dma_data_direction dir = page_pool_get_dma_dir(q->page_pool); -@@ -650,11 +772,15 @@ static int airoha_qdma_rx_process(struct - - skb_reserve(q->skb, AIROHA_RX_HEADROOM); - __skb_put(q->skb, len); -- skb_mark_for_recycle(q->skb); - q->skb->dev = port->dev; -- q->skb->protocol = eth_type_trans(q->skb, port->dev); - q->skb->ip_summed = CHECKSUM_UNNECESSARY; - skb_record_rx_queue(q->skb, qid); -+ -+ if (airoha_qdma_lro_rx_process(q, desc) < 0) -+ goto free_frag; -+ -+ q->skb->protocol = eth_type_trans(q->skb, port->dev); -+ skb_mark_for_recycle(q->skb); - } else { /* scattered frame */ - struct skb_shared_info *shinfo = skb_shinfo(q->skb); - int nr_frags = shinfo->nr_frags; -@@ -743,12 +869,10 @@ static int airoha_qdma_rx_napi_poll(stru - static int airoha_qdma_init_rx_queue(struct airoha_queue *q, - struct airoha_qdma *qdma, int ndesc) - { -- const struct page_pool_params pp_params = { -- .order = 0, -+ struct page_pool_params pp_params = { - .pool_size = 256, - .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, - .dma_dir = DMA_FROM_DEVICE, -- .max_len = PAGE_SIZE, - .nid = NUMA_NO_NODE, - .dev = qdma->eth->dev, - .napi = &q->napi, -@@ -756,9 +880,10 @@ static int airoha_qdma_init_rx_queue(str - struct airoha_eth *eth = qdma->eth; - int qid = q - &qdma->q_rx[0], thr; - dma_addr_t dma_addr; -+ bool lro_q; - -- q->buf_size = PAGE_SIZE / 2; - q->qdma = qdma; -+ lro_q = airoha_qdma_is_lro_queue(q); - - q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry), - GFP_KERNEL); -@@ -770,6 +895,9 @@ static int airoha_qdma_init_rx_queue(str - if (!q->desc) - return -ENOMEM; - -+ pp_params.order = lro_q ? AIROHA_LRO_PAGE_ORDER : 0; -+ pp_params.max_len = PAGE_SIZE << pp_params.order; -+ - q->page_pool = page_pool_create(&pp_params); - if (IS_ERR(q->page_pool)) { - int err = PTR_ERR(q->page_pool); -@@ -778,6 +906,7 @@ static int airoha_qdma_init_rx_queue(str - return err; - } - -+ q->buf_size = lro_q ? pp_params.max_len : pp_params.max_len / 2; - q->ndesc = ndesc; - netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll); - -@@ -2034,6 +2163,67 @@ int airoha_get_fe_port(struct airoha_gdm - } - } - -+static int airoha_dev_set_features(struct net_device *dev, -+ netdev_features_t features) -+{ -+ netdev_features_t diff = dev->features ^ features; -+ struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_qdma *qdma = port->qdma; -+ struct airoha_eth *eth = qdma->eth; -+ int qdma_id = qdma - ð->qdma[0]; -+ int i; -+ -+ if (!(diff & NETIF_F_LRO)) -+ return 0; -+ -+ if (netif_running(dev)) -+ return -EBUSY; -+ -+ /* reset LRO configuration */ -+ if (features & NETIF_F_LRO) { -+ int lro_queue_index = 0; -+ -+ if (airoha_fe_lro_is_enabled(eth, qdma_id)) -+ return 0; -+ -+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -+ struct airoha_queue *q = &qdma->q_rx[i]; -+ u32 size; -+ -+ if (!q->ndesc) -+ continue; -+ -+ if (!airoha_qdma_is_lro_queue(q)) -+ continue; -+ -+ size = SKB_WITH_OVERHEAD(AIROHA_RX_LEN(q->buf_size)); -+ size = min_t(u32, size, CDM_LRO_AGG_SIZE_MASK); -+ airoha_fe_lro_init_rx_queue(eth, qdma_id, -+ lro_queue_index, i, size); -+ lro_queue_index++; -+ } -+ } else { -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *p = eth->ports[i]; -+ -+ if (!p) -+ continue; -+ -+ if (p->qdma != qdma) -+ continue; -+ -+ if (p->dev == dev) -+ continue; -+ -+ if (p->dev->features & NETIF_F_LRO) -+ return 0; -+ } -+ airoha_fe_lro_disable(eth, qdma_id); -+ } -+ -+ return 0; -+} -+ - static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, - struct net_device *dev) - { -@@ -2933,6 +3123,7 @@ static const struct net_device_ops airoh - .ndo_stop = airoha_dev_stop, - .ndo_change_mtu = airoha_dev_change_mtu, - .ndo_select_queue = airoha_dev_select_queue, -+ .ndo_set_features = airoha_dev_set_features, - .ndo_start_xmit = airoha_dev_xmit, - .ndo_get_stats64 = airoha_dev_get_stats64, - .ndo_set_mac_address = airoha_dev_set_macaddr, -@@ -3150,12 +3341,9 @@ static int airoha_alloc_gdm_port(struct - dev->ethtool_ops = &airoha_ethtool_ops; - dev->max_mtu = AIROHA_MAX_MTU; - dev->watchdog_timeo = 5 * HZ; -- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | -- NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | -- NETIF_F_SG | NETIF_F_TSO | -- NETIF_F_HW_TC; -- dev->features |= dev->hw_features; -- dev->vlan_features = dev->hw_features; -+ dev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO; -+ dev->features |= AIROHA_HW_FEATURES; -+ dev->vlan_features = AIROHA_HW_FEATURES; - dev->dev.of_node = np; - SET_NETDEV_DEV(dev, eth->dev); - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -43,6 +43,18 @@ - (_n) == 15 ? 128 : \ - (_n) == 0 ? 1024 : 16) - -+#define AIROHA_LRO_PAGE_ORDER 2 -+#define AIROHA_MAX_NUM_LRO_QUEUES 8 -+#define AIROHA_RXQ_LRO_EN_MASK 0xff000000 -+#define AIROHA_RXQ_LRO_MAX_AGG_COUNT 64 -+#define AIROHA_RXQ_LRO_MAX_AGG_TIME 100 -+#define AIROHA_RXQ_LRO_MAX_AGE_TIME 2000 /* 1ms */ -+ -+#define AIROHA_HW_FEATURES \ -+ (NETIF_F_IP_CSUM | NETIF_F_RXCSUM | \ -+ NETIF_F_TSO6 | NETIF_F_IPV6_CSUM | \ -+ NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_TC) -+ - #define PSE_RSV_PAGES 128 - #define PSE_QUEUE_RSV_PAGES 64 - -@@ -666,6 +678,18 @@ static inline bool airoha_is_7583(struct - return eth->soc->version == 0x7583; - } - -+static inline bool airoha_qdma_is_lro_queue(struct airoha_queue *q) -+{ -+ struct airoha_qdma *qdma = q->qdma; -+ int qid = q - &qdma->q_rx[0]; -+ -+ /* EN7581 SoC supports at most 8 LRO rx queues */ -+ BUILD_BUG_ON(hweight32(AIROHA_RXQ_LRO_EN_MASK) > -+ AIROHA_MAX_NUM_LRO_QUEUES); -+ -+ return !!(AIROHA_RXQ_LRO_EN_MASK & BIT(qid)); -+} -+ - int airoha_get_fe_port(struct airoha_gdm_port *port); - bool airoha_is_valid_gdm_port(struct airoha_eth *eth, - struct airoha_gdm_port *port); ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -122,6 +122,20 @@ - #define CDM_CRSN_QSEL_REASON_MASK(_n) \ - GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) - -+#define REG_CDM_LRO_RXQ(_n, _m) (CDM_BASE(_n) + 0x78 + ((_m) & 0x4)) -+#define LRO_RXQ_MASK(_n) GENMASK(4 + (((_n) & 0x3) << 3), ((_n) & 0x3) << 3) -+ -+#define REG_CDM_LRO_EN(_n) (CDM_BASE(_n) + 0x80) -+#define LRO_RXQ_EN_MASK GENMASK(7, 0) -+ -+#define REG_CDM_LRO_LIMIT(_n) (CDM_BASE(_n) + 0x84) -+#define CDM_LRO_AGG_NUM_MASK GENMASK(23, 16) -+#define CDM_LRO_AGG_SIZE_MASK GENMASK(15, 0) -+ -+#define REG_CDM_LRO_AGE_TIME(_n) (CDM_BASE(_n) + 0x88) -+#define CDM_LRO_AGE_TIME_MASK GENMASK(31, 16) -+#define CDM_LRO_AGG_TIME_MASK GENMASK(15, 0) -+ - #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) - #define GDM_PAD_EN_MASK BIT(28) - #define GDM_DROP_CRC_ERR_MASK BIT(23) -@@ -895,9 +909,15 @@ - #define QDMA_ETH_RXMSG_SPORT_MASK GENMASK(25, 21) - #define QDMA_ETH_RXMSG_CRSN_MASK GENMASK(20, 16) - #define QDMA_ETH_RXMSG_PPE_ENTRY_MASK GENMASK(15, 0) -+/* RX MSG2 */ -+#define QDMA_ETH_RXMSG_AGG_COUNT_MASK GENMASK(31, 24) -+#define QDMA_ETH_RXMSG_L2_LEN_MASK GENMASK(6, 0) -+/* RX MSG3 */ -+#define QDMA_ETH_RXMSG_AGG_LEN_MASK GENMASK(31, 16) -+#define QDMA_ETH_RXMSG_TCP_WIN_MASK GENMASK(15, 0) - - struct airoha_qdma_desc { -- __le32 rsv; -+ __le32 tcp_ts_reply; - __le32 ctrl; - __le32 addr; - __le32 data; diff --git a/target/linux/airoha/patches-6.12/920-01-net-airoha-Introduce-airoha_gdm_dev-struct.patch b/target/linux/airoha/patches-6.12/920-01-net-airoha-Introduce-airoha_gdm_dev-struct.patch deleted file mode 100644 index 0bb339c9104..00000000000 --- a/target/linux/airoha/patches-6.12/920-01-net-airoha-Introduce-airoha_gdm_dev-struct.patch +++ /dev/null @@ -1,1018 +0,0 @@ -From e15783f7c987e199ecf80b3d858ed5a86d33c508 Mon Sep 17 00:00:00 2001 -Message-ID: -From: Lorenzo Bianconi -Date: Sat, 1 Nov 2025 11:25:52 +0100 -Subject: [PATCH 01/13] net: airoha: Introduce airoha_gdm_dev struct - -EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3 -or GDM4 ports via a hw arbiter that manages the traffic in a TDM manner. -As a result multiple net_devices can connect to the same GDM{3,4} port -and there is a theoretical "1:n" relation between GDM port and -net_devices. -Introduce airoha_gdm_dev struct to collect net_device related info (e.g. -net_device and external phy pointer). Please note this is just a -preliminary patch and we are still supporting a single net_device for -each GDM port. Subsequent patches will add support for multiple net_devices -connected to the same GDM port. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 312 ++++++++++++++--------- - drivers/net/ethernet/airoha/airoha_eth.h | 13 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 17 +- - 3 files changed, 206 insertions(+), 136 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -738,6 +738,7 @@ static int airoha_qdma_rx_process(struct - struct airoha_qdma_desc *desc = &q->desc[q->tail]; - u32 hash, reason, msg1, desc_ctrl; - struct airoha_gdm_port *port; -+ struct net_device *netdev; - int data_len, len, p; - struct page *page; - -@@ -764,6 +765,10 @@ static int airoha_qdma_rx_process(struct - goto free_frag; - - port = eth->ports[p]; -+ if (!port->dev) -+ goto free_frag; -+ -+ netdev = port->dev->dev; - if (!q->skb) { /* first buffer */ - q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM, - q->buf_size); -@@ -772,14 +777,14 @@ static int airoha_qdma_rx_process(struct - - skb_reserve(q->skb, AIROHA_RX_HEADROOM); - __skb_put(q->skb, len); -- q->skb->dev = port->dev; -+ q->skb->dev = netdev; - q->skb->ip_summed = CHECKSUM_UNNECESSARY; - skb_record_rx_queue(q->skb, qid); - - if (airoha_qdma_lro_rx_process(q, desc) < 0) - goto free_frag; - -- q->skb->protocol = eth_type_trans(q->skb, port->dev); -+ q->skb->protocol = eth_type_trans(q->skb, netdev); - skb_mark_for_recycle(q->skb); - } else { /* scattered frame */ - struct skb_shared_info *shinfo = skb_shinfo(q->skb); -@@ -796,7 +801,7 @@ static int airoha_qdma_rx_process(struct - if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl)) - continue; - -- if (netdev_uses_dsa(port->dev)) { -+ if (netdev_uses_dsa(netdev)) { - /* PPE module requires untagged packets to work - * properly and it provides DSA port index via the - * DMA descriptor. Report DSA tag to the DSA stack -@@ -993,6 +998,7 @@ static void airoha_qdma_wake_netdev_txqs - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -+ struct airoha_gdm_dev *dev; - int j; - - if (!port) -@@ -1001,11 +1007,12 @@ static void airoha_qdma_wake_netdev_txqs - if (port->qdma != qdma) - continue; - -- for (j = 0; j < port->dev->num_tx_queues; j++) { -+ dev = port->dev; -+ for (j = 0; j < dev->dev->num_tx_queues; j++) { - if (airoha_qdma_get_txq(qdma, j) != qid) - continue; - -- netif_wake_subqueue(port->dev, j); -+ netif_wake_subqueue(dev->dev, j); - } - } - q->txq_stopped = false; -@@ -1849,33 +1856,34 @@ static void airoha_update_hw_stats(struc - spin_unlock(&port->stats.lock); - } - --static int airoha_dev_open(struct net_device *dev) -+static int airoha_dev_open(struct net_device *netdev) - { -- int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN; -- struct airoha_gdm_port *port = netdev_priv(dev); -+ int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN; -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_qdma *qdma = port->qdma; - u32 pse_port = FE_PSE_PORT_PPE1; - - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { -- err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0); -+ err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0); - if (err) { -- netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -+ netdev_err(netdev, "%s: could not attach PHY: %d\n", __func__, - err); - return err; - } - -- phylink_start(port->phylink); -+ phylink_start(dev->phylink); - } - #endif - -- netif_tx_start_all_queues(dev); -+ netif_tx_start_all_queues(netdev); - err = airoha_set_vip_for_gdm_port(port, true); - if (err) - return err; - - /* It seems GDM3 and GDM4 needs SPORT enabled to correctly work */ -- if (netdev_uses_dsa(dev) || port->id > 2) -+ if (netdev_uses_dsa(netdev) || port->id > 2) - airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id), - GDM_STAG_EN_MASK); - else -@@ -1903,16 +1911,17 @@ static int airoha_dev_open(struct net_de - return 0; - } - --static int airoha_dev_stop(struct net_device *dev) -+static int airoha_dev_stop(struct net_device *netdev) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_qdma *qdma = port->qdma; - int i; - -- netif_tx_disable(dev); -+ netif_tx_disable(netdev); - airoha_set_vip_for_gdm_port(port, false); -- for (i = 0; i < dev->num_tx_queues; i++) -- netdev_tx_reset_subqueue(dev, i); -+ for (i = 0; i < netdev->num_tx_queues; i++) -+ netdev_tx_reset_subqueue(netdev, i); - - airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id), - FE_PSE_PORT_DROP); -@@ -1932,24 +1941,25 @@ static int airoha_dev_stop(struct net_de - - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { -- phylink_stop(port->phylink); -- phylink_disconnect_phy(port->phylink); -+ phylink_stop(dev->phylink); -+ phylink_disconnect_phy(dev->phylink); - } - #endif - - return 0; - } - --static int airoha_dev_set_macaddr(struct net_device *dev, void *p) -+static int airoha_dev_set_macaddr(struct net_device *netdev, void *p) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - int err; - -- err = eth_mac_addr(dev, p); -+ err = eth_mac_addr(netdev, p); - if (err) - return err; - -- airoha_set_macaddr(port, dev->dev_addr); -+ airoha_set_macaddr(port, netdev->dev_addr); - - return 0; - } -@@ -2015,16 +2025,17 @@ static int airoha_set_gdm2_loopback(stru - return 0; - } - --static int airoha_dev_init(struct net_device *dev) -+static int airoha_dev_init(struct net_device *netdev) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -- struct airoha_eth *eth = port->eth; -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; - int i; - - /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ - port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; -- port->dev->irq = port->qdma->irq_banks[0].irq; -- airoha_set_macaddr(port, dev->dev_addr); -+ dev->dev->irq = port->qdma->irq_banks[0].irq; -+ airoha_set_macaddr(port, netdev->dev_addr); - - switch (port->id) { - case AIROHA_GDM3_IDX: -@@ -2049,10 +2060,11 @@ static int airoha_dev_init(struct net_de - return 0; - } - --static void airoha_dev_get_stats64(struct net_device *dev, -+static void airoha_dev_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 *storage) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - unsigned int start; - - airoha_update_hw_stats(port); -@@ -2071,36 +2083,39 @@ static void airoha_dev_get_stats64(struc - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } - --static int airoha_dev_change_mtu(struct net_device *dev, int mtu) -+static int airoha_dev_change_mtu(struct net_device *netdev, int mtu) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = port->qdma->eth; - u32 len = ETH_HLEN + mtu + ETH_FCS_LEN; - - airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), - GDM_LONG_LEN_MASK, - FIELD_PREP(GDM_LONG_LEN_MASK, len)); -- WRITE_ONCE(dev->mtu, mtu); -+ WRITE_ONCE(netdev->mtu, mtu); - - return 0; - } - --static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb, -+static u16 airoha_dev_select_queue(struct net_device *netdev, -+ struct sk_buff *skb, - struct net_device *sb_dev) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - int queue, channel; - - /* For dsa device select QoS channel according to the dsa user port - * index, rely on port id otherwise. Select QoS queue based on the - * skb priority. - */ -- channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id; -+ channel = netdev_uses_dsa(netdev) ? skb_get_queue_mapping(skb) : port->id; - channel = channel % AIROHA_NUM_QOS_CHANNELS; - queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */ - queue = channel * AIROHA_NUM_QOS_QUEUES + queue; - -- return queue < dev->num_tx_queues ? queue : 0; -+ return queue < netdev->num_tx_queues ? queue : 0; - } - - static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev) -@@ -2163,11 +2178,12 @@ int airoha_get_fe_port(struct airoha_gdm - } - } - --static int airoha_dev_set_features(struct net_device *dev, -+static int airoha_dev_set_features(struct net_device *netdev, - netdev_features_t features) - { -- netdev_features_t diff = dev->features ^ features; -- struct airoha_gdm_port *port = netdev_priv(dev); -+ netdev_features_t diff = netdev->features ^ features; -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_qdma *qdma = port->qdma; - struct airoha_eth *eth = qdma->eth; - int qdma_id = qdma - ð->qdma[0]; -@@ -2176,7 +2192,7 @@ static int airoha_dev_set_features(struc - if (!(diff & NETIF_F_LRO)) - return 0; - -- if (netif_running(dev)) -+ if (netif_running(netdev)) - return -EBUSY; - - /* reset LRO configuration */ -@@ -2205,6 +2221,7 @@ static int airoha_dev_set_features(struc - } else { - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *p = eth->ports[i]; -+ struct airoha_gdm_dev *d; - - if (!p) - continue; -@@ -2212,10 +2229,11 @@ static int airoha_dev_set_features(struc - if (p->qdma != qdma) - continue; - -- if (p->dev == dev) -+ d = p->dev; -+ if (d->dev == netdev) - continue; - -- if (p->dev->features & NETIF_F_LRO) -+ if (d->dev->features & NETIF_F_LRO) - return 0; - } - airoha_fe_lro_disable(eth, qdma_id); -@@ -2225,9 +2243,10 @@ static int airoha_dev_set_features(struc - } - - static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, -- struct net_device *dev) -+ struct net_device *netdev) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_qdma *qdma = port->qdma; - u32 nr_frags, tag, msg0, msg1, len; - struct airoha_queue_entry *e; -@@ -2240,7 +2259,7 @@ static netdev_tx_t airoha_dev_xmit(struc - u8 fport; - - qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb)); -- tag = airoha_get_dsa_tag(skb, dev); -+ tag = airoha_get_dsa_tag(skb, netdev); - - msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, - qid / AIROHA_NUM_QOS_QUEUES) | -@@ -2276,7 +2295,7 @@ static netdev_tx_t airoha_dev_xmit(struc - - spin_lock_bh(&q->lock); - -- txq = skb_get_tx_queue(dev, skb); -+ txq = skb_get_tx_queue(netdev, skb); - nr_frags = 1 + skb_shinfo(skb)->nr_frags; - - if (q->queued + nr_frags >= q->ndesc) { -@@ -2300,9 +2319,9 @@ static netdev_tx_t airoha_dev_xmit(struc - dma_addr_t addr; - u32 val; - -- addr = dma_map_single(dev->dev.parent, data, len, -+ addr = dma_map_single(netdev->dev.parent, data, len, - DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(dev->dev.parent, addr))) -+ if (unlikely(dma_mapping_error(netdev->dev.parent, addr))) - goto error_unmap; - - list_move_tail(&e->list, &tx_list); -@@ -2351,7 +2370,7 @@ static netdev_tx_t airoha_dev_xmit(struc - - error_unmap: - list_for_each_entry(e, &tx_list, list) { -- dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len, -+ dma_unmap_single(netdev->dev.parent, e->dma_addr, e->dma_len, - DMA_TO_DEVICE); - e->dma_addr = 0; - } -@@ -2360,25 +2379,27 @@ error_unmap: - spin_unlock_bh(&q->lock); - error: - dev_kfree_skb_any(skb); -- dev->stats.tx_dropped++; -+ netdev->stats.tx_dropped++; - - return NETDEV_TX_OK; - } - --static void airoha_ethtool_get_drvinfo(struct net_device *dev, -+static void airoha_ethtool_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *info) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = port->qdma->eth; - - strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); - strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); - } - --static void airoha_ethtool_get_mac_stats(struct net_device *dev, -+static void airoha_ethtool_get_mac_stats(struct net_device *netdev, - struct ethtool_eth_mac_stats *stats) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - unsigned int start; - - airoha_update_hw_stats(port); -@@ -2406,11 +2427,12 @@ static const struct ethtool_rmon_hist_ra - }; - - static void --airoha_ethtool_get_rmon_stats(struct net_device *dev, -+airoha_ethtool_get_rmon_stats(struct net_device *netdev, - struct ethtool_rmon_stats *stats, - const struct ethtool_rmon_hist_range **ranges) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_hw_stats *hw_stats = &port->stats; - unsigned int start; - -@@ -2435,11 +2457,12 @@ airoha_ethtool_get_rmon_stats(struct net - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } - --static int airoha_qdma_set_chan_tx_sched(struct net_device *dev, -+static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev, - int channel, enum tx_sched_mode mode, - const u16 *weights, u8 n_weights) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - int i; - - for (i = 0; i < AIROHA_NUM_TX_RING; i++) -@@ -2524,10 +2547,12 @@ static int airoha_qdma_set_tx_ets_sched( - ARRAY_SIZE(w)); - } - --static int airoha_qdma_get_tx_ets_stats(struct net_device *dev, int channel, -+static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel, - struct tc_ets_qopt_offload *opt) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; -+ - u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, - REG_CNTR_VAL(channel << 1)); - u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, -@@ -2789,11 +2814,12 @@ static int airoha_qdma_set_trtcm_token_b - mode, val); - } - --static int airoha_qdma_set_tx_rate_limit(struct net_device *dev, -+static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev, - int channel, u32 rate, - u32 bucket_size) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - int i, err; - - for (i = 0; i <= TRTCM_PEAK_MODE; i++) { -@@ -2813,20 +2839,22 @@ static int airoha_qdma_set_tx_rate_limit - return 0; - } - --static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev, -+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev, - struct tc_htb_qopt_offload *opt) - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; - u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ -- int err, num_tx_queues = dev->real_num_tx_queues; -- struct airoha_gdm_port *port = netdev_priv(dev); -+ int err, num_tx_queues = netdev->real_num_tx_queues; -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - - if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); - return -EINVAL; - } - -- err = airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum); -+ err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate, -+ opt->quantum); - if (err) { - NL_SET_ERR_MSG_MOD(opt->extack, - "failed configuring htb offload"); -@@ -2836,9 +2864,10 @@ static int airoha_tc_htb_alloc_leaf_queu - if (opt->command == TC_HTB_NODE_MODIFY) - return 0; - -- err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1); -+ err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1); - if (err) { -- airoha_qdma_set_tx_rate_limit(dev, channel, 0, opt->quantum); -+ airoha_qdma_set_tx_rate_limit(netdev, channel, 0, -+ opt->quantum); - NL_SET_ERR_MSG_MOD(opt->extack, - "failed setting real_num_tx_queues"); - return err; -@@ -2928,11 +2957,12 @@ static int airoha_tc_matchall_act_valida - return 0; - } - --static int airoha_dev_tc_matchall(struct net_device *dev, -+static int airoha_dev_tc_matchall(struct net_device *netdev, - struct tc_cls_matchall_offload *f) - { - enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT; -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - u32 rate = 0, bucket_size = 0; - - switch (f->command) { -@@ -2967,18 +2997,19 @@ static int airoha_dev_tc_matchall(struct - static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type, - void *type_data, void *cb_priv) - { -- struct net_device *dev = cb_priv; -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct net_device *netdev = cb_priv; -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = port->qdma->eth; - -- if (!tc_can_offload(dev)) -+ if (!tc_can_offload(netdev)) - return -EOPNOTSUPP; - - switch (type) { - case TC_SETUP_CLSFLOWER: - return airoha_ppe_setup_tc_block_cb(ð->ppe->dev, type_data); - case TC_SETUP_CLSMATCHALL: -- return airoha_dev_tc_matchall(dev, type_data); -+ return airoha_dev_tc_matchall(netdev, type_data); - default: - return -EOPNOTSUPP; - } -@@ -3025,47 +3056,51 @@ static int airoha_dev_setup_tc_block(str - } - } - --static void airoha_tc_remove_htb_queue(struct net_device *dev, int queue) -+static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - -- netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1); -- airoha_qdma_set_tx_rate_limit(dev, queue + 1, 0, 0); -+ netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1); -+ airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0); - clear_bit(queue, port->qos_sq_bmap); - } - --static int airoha_tc_htb_delete_leaf_queue(struct net_device *dev, -+static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev, - struct tc_htb_qopt_offload *opt) - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - - if (!test_bit(channel, port->qos_sq_bmap)) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); - return -EINVAL; - } - -- airoha_tc_remove_htb_queue(dev, channel); -+ airoha_tc_remove_htb_queue(netdev, channel); - - return 0; - } - --static int airoha_tc_htb_destroy(struct net_device *dev) -+static int airoha_tc_htb_destroy(struct net_device *netdev) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - int q; - - for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) -- airoha_tc_remove_htb_queue(dev, q); -+ airoha_tc_remove_htb_queue(netdev, q); - - return 0; - } - --static int airoha_tc_get_htb_get_leaf_queue(struct net_device *dev, -+static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev, - struct tc_htb_qopt_offload *opt) - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - - if (!test_bit(channel, port->qos_sq_bmap)) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); -@@ -3101,8 +3136,8 @@ static int airoha_tc_setup_qdisc_htb(str - return 0; - } - --static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type, -- void *type_data) -+static int airoha_dev_tc_setup(struct net_device *dev, -+ enum tc_setup_type type, void *type_data) - { - switch (type) { - case TC_SETUP_QDISC_ETS: -@@ -3174,13 +3209,18 @@ static void airoha_metadata_dst_free(str - } - } - --bool airoha_is_valid_gdm_port(struct airoha_eth *eth, -- struct airoha_gdm_port *port) -+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth, -+ struct airoha_gdm_dev *dev) - { - int i; - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -- if (eth->ports[i] == port) -+ struct airoha_gdm_port *port = eth->ports[i]; -+ -+ if (!port) -+ continue; -+ -+ if (port->dev == dev) - return true; - } - -@@ -3192,8 +3232,9 @@ static void airoha_mac_link_up(struct ph - unsigned int mode, phy_interface_t interface, - int speed, int duplex, bool tx_pause, bool rx_pause) - { -- struct airoha_gdm_port *port = container_of(config, struct airoha_gdm_port, -- phylink_config); -+ struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev, -+ phylink_config); -+ struct airoha_gdm_port *port = dev->port; - struct airoha_qdma *qdma = port->qdma; - struct airoha_eth *eth = qdma->eth; - u32 frag_size_tx, frag_size_rx; -@@ -3249,65 +3290,122 @@ static int airoha_fill_available_pcs(str - &num_available_pcs); - } - --static int airoha_setup_phylink(struct net_device *dev) -+static int airoha_setup_phylink(struct net_device *netdev) - { -- struct airoha_gdm_port *port = netdev_priv(dev); -- struct device_node *np = dev->dev.of_node; -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct device_node *np = netdev->dev.of_node; - phy_interface_t phy_mode; - struct phylink *phylink; - int err; - - err = of_get_phy_mode(np, &phy_mode); - if (err) { -- dev_err(&dev->dev, "incorrect phy-mode\n"); -+ dev_err(&netdev->dev, "incorrect phy-mode\n"); - return err; - } - -- port->phylink_config.dev = &dev->dev; -- port->phylink_config.type = PHYLINK_NETDEV; -- port->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -- MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD | -- MAC_5000FD | MAC_10000FD; -+ dev->phylink_config.dev = &netdev->dev; -+ dev->phylink_config.type = PHYLINK_NETDEV; -+ dev->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -+ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD | -+ MAC_5000FD | MAC_10000FD; - -- err = fwnode_phylink_pcs_parse(dev_fwnode(&dev->dev), NULL, -- &port->phylink_config.num_available_pcs); -+ err = fwnode_phylink_pcs_parse(dev_fwnode(&netdev->dev), NULL, -+ &dev->phylink_config.num_available_pcs); - if (err) - return err; - -- port->phylink_config.fill_available_pcs = airoha_fill_available_pcs; -+ dev->phylink_config.fill_available_pcs = airoha_fill_available_pcs; - - __set_bit(PHY_INTERFACE_MODE_SGMII, -- port->phylink_config.supported_interfaces); -+ dev->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_1000BASEX, -- port->phylink_config.supported_interfaces); -+ dev->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_2500BASEX, -- port->phylink_config.supported_interfaces); -+ dev->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_10GBASER, -- port->phylink_config.supported_interfaces); -+ dev->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_USXGMII, -- port->phylink_config.supported_interfaces); -+ dev->phylink_config.supported_interfaces); - -- phy_interface_copy(port->phylink_config.pcs_interfaces, -- port->phylink_config.supported_interfaces); -+ phy_interface_copy(dev->phylink_config.pcs_interfaces, -+ dev->phylink_config.supported_interfaces); - -- phylink = phylink_create(&port->phylink_config, -+ phylink = phylink_create(&dev->phylink_config, - of_fwnode_handle(np), - phy_mode, &airoha_phylink_ops); - if (IS_ERR(phylink)) - return PTR_ERR(phylink); - -- port->phylink = phylink; -+ dev->phylink = phylink; - - return err; - } - #endif - -+static int airoha_alloc_gdm_device(struct airoha_eth *eth, -+ struct airoha_gdm_port *port, -+ struct device_node *np) -+{ -+ struct airoha_gdm_dev *dev; -+ struct net_device *netdev; -+ int err; -+ -+ netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev), -+ AIROHA_NUM_NETDEV_TX_RINGS, -+ AIROHA_NUM_RX_RING); -+ if (!netdev) { -+ dev_err(eth->dev, "alloc_etherdev failed\n"); -+ return -ENOMEM; -+ } -+ -+ netdev->netdev_ops = &airoha_netdev_ops; -+ netdev->ethtool_ops = &airoha_ethtool_ops; -+ netdev->max_mtu = AIROHA_MAX_MTU; -+ netdev->watchdog_timeo = 5 * HZ; -+ netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO; -+ netdev->features |= AIROHA_HW_FEATURES; -+ netdev->vlan_features = AIROHA_HW_FEATURES; -+ netdev->dev.of_node = np; -+ SET_NETDEV_DEV(netdev, eth->dev); -+ -+ /* reserve hw queues for HTB offloading */ -+ err = netif_set_real_num_tx_queues(netdev, AIROHA_NUM_TX_RING); -+ if (err) -+ return err; -+ -+ err = of_get_ethdev_address(np, netdev); -+ if (err) { -+ if (err == -EPROBE_DEFER) -+ return err; -+ -+ eth_hw_addr_random(netdev); -+ dev_info(eth->dev, "generated random MAC address %pM\n", -+ netdev->dev_addr); -+ } -+ -+ dev = netdev_priv(netdev); -+ dev->dev = netdev; -+ dev->port = port; -+ port->dev = dev; -+ dev->eth = eth; -+ -+#if defined(CONFIG_PCS_AIROHA) -+ if (airhoa_is_phy_external(port)) { -+ err = airoha_setup_phylink(netdev); -+ if (err) -+ return err; -+ } -+#endif -+ -+ return 0; -+} -+ - static int airoha_alloc_gdm_port(struct airoha_eth *eth, - struct device_node *np) - { - const __be32 *id_ptr = of_get_property(np, "reg", NULL); - struct airoha_gdm_port *port; -- struct net_device *dev; - int err, p; - u32 id; - -@@ -3329,58 +3427,22 @@ static int airoha_alloc_gdm_port(struct - return -EINVAL; - } - -- dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port), -- AIROHA_NUM_NETDEV_TX_RINGS, -- AIROHA_NUM_RX_RING); -- if (!dev) { -- dev_err(eth->dev, "alloc_etherdev failed\n"); -+ port = devm_kzalloc(eth->dev, sizeof(*port), GFP_KERNEL); -+ if (!port) - return -ENOMEM; -- } -- -- dev->netdev_ops = &airoha_netdev_ops; -- dev->ethtool_ops = &airoha_ethtool_ops; -- dev->max_mtu = AIROHA_MAX_MTU; -- dev->watchdog_timeo = 5 * HZ; -- dev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO; -- dev->features |= AIROHA_HW_FEATURES; -- dev->vlan_features = AIROHA_HW_FEATURES; -- dev->dev.of_node = np; -- SET_NETDEV_DEV(dev, eth->dev); -- -- /* reserve hw queues for HTB offloading */ -- err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING); -- if (err) -- return err; - -- err = of_get_ethdev_address(np, dev); -- if (err) { -- if (err == -EPROBE_DEFER) -- return err; -- -- eth_hw_addr_random(dev); -- dev_info(eth->dev, "generated random MAC address %pM\n", -- dev->dev_addr); -- } -- -- port = netdev_priv(dev); - u64_stats_init(&port->stats.syncp); - spin_lock_init(&port->stats.lock); -- port->eth = eth; -- port->dev = dev; - port->id = id; - /* XXX: Read nbq from DTS */ - port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; - eth->ports[p] = port; - --#if defined(CONFIG_PCS_AIROHA) -- if (airhoa_is_phy_external(port)) { -- err = airoha_setup_phylink(dev); -- if (err) -- return err; -- } --#endif -+ err = airoha_metadata_dst_alloc(port); -+ if (err) -+ return err; - -- return airoha_metadata_dst_alloc(port); -+ return airoha_alloc_gdm_device(eth, port, np); - } - - static int airoha_register_gdm_devices(struct airoha_eth *eth) -@@ -3394,7 +3456,7 @@ static int airoha_register_gdm_devices(s - if (!port) - continue; - -- err = register_netdev(port->dev); -+ err = register_netdev(port->dev->dev); - if (err) - return err; - } -@@ -3503,16 +3565,18 @@ error_napi_stop: - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -+ struct airoha_gdm_dev *dev; - - if (!port) - continue; - -- if (port->dev->reg_state == NETREG_REGISTERED) { -+ dev = port->dev; -+ if (dev && dev->dev->reg_state == NETREG_REGISTERED) { - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) -- phylink_destroy(port->phylink); -+ phylink_destroy(dev->phylink); - #endif -- unregister_netdev(port->dev); -+ unregister_netdev(dev->dev); - } - airoha_metadata_dst_free(port); - } -@@ -3534,15 +3598,19 @@ static void airoha_remove(struct platfor - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -+ struct airoha_gdm_dev *dev; - - if (!port) - continue; - - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) -- phylink_destroy(port->phylink); -+ phylink_destroy(dev->phylink); - #endif -- unregister_netdev(port->dev); -+ -+ dev = port->dev; -+ if (dev) -+ unregister_netdev(dev->dev); - airoha_metadata_dst_free(port); - } - airoha_hw_cleanup(eth); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -547,17 +547,22 @@ struct airoha_qdma { - struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; - }; - --struct airoha_gdm_port { -- struct airoha_qdma *qdma; -- struct airoha_eth *eth; -+struct airoha_gdm_dev { -+ struct airoha_gdm_port *port; - struct net_device *dev; -- int id; -- int nbq; -+ struct airoha_eth *eth; - - #if defined(CONFIG_PCS_AIROHA) - struct phylink *phylink; - struct phylink_config phylink_config; - #endif -+}; -+ -+struct airoha_gdm_port { -+ struct airoha_qdma *qdma; -+ struct airoha_gdm_dev *dev; -+ int id; -+ int nbq; - - struct airoha_hw_stats stats; - -@@ -691,8 +696,8 @@ static inline bool airoha_qdma_is_lro_qu - } - - int airoha_get_fe_port(struct airoha_gdm_port *port); --bool airoha_is_valid_gdm_port(struct airoha_eth *eth, -- struct airoha_gdm_port *port); -+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth, -+ struct airoha_gdm_dev *dev); - - void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, - u8 fport); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -297,12 +297,12 @@ static void airoha_ppe_foe_set_bridge_ad - - static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, - struct airoha_foe_entry *hwe, -- struct net_device *dev, int type, -+ struct net_device *netdev, int type, - struct airoha_flow_data *data, - int l4proto, u8 dsfield) - { - u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val; -- int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev); -+ int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&netdev); - struct airoha_foe_mac_info_common *l2; - u8 smac_id = 0xf; - -@@ -318,10 +318,11 @@ static int airoha_ppe_foe_entry_prepare( - hwe->ib1 = val; - - val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); -- if (dev) { -+ if (netdev) { - struct airoha_wdma_info info = {}; - -- if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) { -+ if (!airoha_ppe_get_wdma_info(netdev, data->eth.h_dest, -+ &info)) { - val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) | - FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, - FE_PSE_PORT_CDM4); -@@ -331,12 +332,14 @@ static int airoha_ppe_foe_entry_prepare( - FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID, - info.wcid); - } else { -- struct airoha_gdm_port *port = netdev_priv(dev); -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); - u8 pse_port, channel, priority; -+ struct airoha_gdm_port *port; - -- if (!airoha_is_valid_gdm_port(eth, port)) -+ if (!airoha_is_valid_gdm_dev(eth, dev)) - return -EINVAL; - -+ port = dev->port; - if (dsa_port >= 0 || eth->ports[1]) - pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 - : port->id; -@@ -1483,7 +1486,7 @@ void airoha_ppe_check_skb(struct airoha_ - void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port) - { - struct airoha_eth *eth = port->qdma->eth; -- struct net_device *dev = port->dev; -+ struct net_device *dev = port->dev->dev; - const u8 *addr = dev->dev_addr; - u32 val; - diff --git a/target/linux/airoha/patches-6.12/920-02-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch b/target/linux/airoha/patches-6.12/920-02-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch deleted file mode 100644 index 6b2ab1c70f6..00000000000 --- a/target/linux/airoha/patches-6.12/920-02-net-airoha-Move-airoha_qdma-pointer-in-airoha_gdm_de.patch +++ /dev/null @@ -1,495 +0,0 @@ -From f62cea6483cc55360863d66300790a5fb9de5f7c Mon Sep 17 00:00:00 2001 -Message-ID: -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Tue, 24 Feb 2026 18:43:05 +0100 -Subject: [PATCH 02/13] net: airoha: Move airoha_qdma pointer in airoha_gdm_dev - struct - -Move airoha_qdma pointer from airoha_gdm_port struct to airoha_gdm_dev -one since the QDMA block used depends on the particular net_device -WAN/LAN configuration and in the current codebase net_device pointer is -associated to airoha_gdm_dev struct. -This is a preliminary patch to support multiple net_devices connected -to the same GDM{3,4} port via an external hw arbiter. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 105 +++++++++++------------ - drivers/net/ethernet/airoha/airoha_eth.h | 9 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 17 ++-- - 3 files changed, 64 insertions(+), 67 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -80,9 +80,10 @@ static bool airhoa_is_phy_external(struc - } - #endif - --static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr) -+static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr) - { -- struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; - u32 val, reg; - - reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H -@@ -94,7 +95,7 @@ static void airoha_set_macaddr(struct ai - airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); - airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); - -- airoha_ppe_init_upd_mem(port); -+ airoha_ppe_init_upd_mem(dev); - } - - static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, -@@ -110,10 +111,10 @@ static void airoha_set_gdm_port_fwd_cfg( - FIELD_PREP(GDM_UCFQ_MASK, val)); - } - --static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port, -- bool enable) -+static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable) - { -- struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; - u32 vip_port; - - vip_port = eth->soc->ops.get_vip_port(port, port->nbq); -@@ -1004,10 +1005,13 @@ static void airoha_qdma_wake_netdev_txqs - if (!port) - continue; - -- if (port->qdma != qdma) -+ dev = port->dev; -+ if (!dev) -+ continue; -+ -+ if (dev->qdma != qdma) - continue; - -- dev = port->dev; - for (j = 0; j < dev->dev->num_tx_queues; j++) { - if (airoha_qdma_get_txq(qdma, j) != qid) - continue; -@@ -1712,9 +1716,10 @@ static void airoha_qdma_stop_napi(struct - } - } - --static void airoha_update_hw_stats(struct airoha_gdm_port *port) -+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev) - { -- struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; - u32 val, i = 0; - - spin_lock(&port->stats.lock); -@@ -1861,7 +1866,7 @@ static int airoha_dev_open(struct net_de - int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN; - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; -- struct airoha_qdma *qdma = port->qdma; -+ struct airoha_qdma *qdma = dev->qdma; - u32 pse_port = FE_PSE_PORT_PPE1; - - #if defined(CONFIG_PCS_AIROHA) -@@ -1878,7 +1883,7 @@ static int airoha_dev_open(struct net_de - #endif - - netif_tx_start_all_queues(netdev); -- err = airoha_set_vip_for_gdm_port(port, true); -+ err = airoha_set_vip_for_gdm_port(dev, true); - if (err) - return err; - -@@ -1915,11 +1920,11 @@ static int airoha_dev_stop(struct net_de - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; -- struct airoha_qdma *qdma = port->qdma; -+ struct airoha_qdma *qdma = dev->qdma; - int i; - - netif_tx_disable(netdev); -- airoha_set_vip_for_gdm_port(port, false); -+ airoha_set_vip_for_gdm_port(dev, false); - for (i = 0; i < netdev->num_tx_queues; i++) - netdev_tx_reset_subqueue(netdev, i); - -@@ -1952,21 +1957,21 @@ static int airoha_dev_stop(struct net_de - static int airoha_dev_set_macaddr(struct net_device *netdev, void *p) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - int err; - - err = eth_mac_addr(netdev, p); - if (err) - return err; - -- airoha_set_macaddr(port, netdev->dev_addr); -+ airoha_set_macaddr(dev, netdev->dev_addr); - - return 0; - } - --static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port) -+static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev) - { -- struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; - u32 val, pse_port, chan; - int i, src_port; - -@@ -2013,7 +2018,7 @@ static int airoha_set_gdm2_loopback(stru - __field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2)); - - for (i = 0; i < eth->soc->num_ppe; i++) -- airoha_ppe_set_cpu_port(port, i, AIROHA_GDM2_IDX); -+ airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX); - - if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) { - u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq); -@@ -2033,9 +2038,9 @@ static int airoha_dev_init(struct net_de - int i; - - /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ -- port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; -- dev->dev->irq = port->qdma->irq_banks[0].irq; -- airoha_set_macaddr(port, netdev->dev_addr); -+ dev->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; -+ dev->dev->irq = dev->qdma->irq_banks[0].irq; -+ airoha_set_macaddr(dev, netdev->dev_addr); - - switch (port->id) { - case AIROHA_GDM3_IDX: -@@ -2044,7 +2049,7 @@ static int airoha_dev_init(struct net_de - if (!eth->ports[1]) { - int err; - -- err = airoha_set_gdm2_loopback(port); -+ err = airoha_set_gdm2_loopback(dev); - if (err) - return err; - } -@@ -2054,8 +2059,7 @@ static int airoha_dev_init(struct net_de - } - - for (i = 0; i < eth->soc->num_ppe; i++) -- airoha_ppe_set_cpu_port(port, i, -- airoha_get_fe_port(port)); -+ airoha_ppe_set_cpu_port(dev, i, airoha_get_fe_port(dev)); - - return 0; - } -@@ -2067,7 +2071,7 @@ static void airoha_dev_get_stats64(struc - struct airoha_gdm_port *port = dev->port; - unsigned int start; - -- airoha_update_hw_stats(port); -+ airoha_update_hw_stats(dev); - do { - start = u64_stats_fetch_begin(&port->stats.syncp); - storage->rx_packets = port->stats.rx_ok_pkts; -@@ -2087,8 +2091,8 @@ static int airoha_dev_change_mtu(struct - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; -- struct airoha_eth *eth = port->qdma->eth; - u32 len = ETH_HLEN + mtu + ETH_FCS_LEN; -+ struct airoha_eth *eth = dev->eth; - - airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), - GDM_LONG_LEN_MASK, -@@ -2162,10 +2166,10 @@ static u32 airoha_get_dsa_tag(struct sk_ - #endif - } - --int airoha_get_fe_port(struct airoha_gdm_port *port) -+int airoha_get_fe_port(struct airoha_gdm_dev *dev) - { -- struct airoha_qdma *qdma = port->qdma; -- struct airoha_eth *eth = qdma->eth; -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; - - switch (eth->soc->version) { - case 0x7583: -@@ -2183,8 +2187,7 @@ static int airoha_dev_set_features(struc - { - netdev_features_t diff = netdev->features ^ features; - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; -- struct airoha_qdma *qdma = port->qdma; -+ struct airoha_qdma *qdma = dev->qdma; - struct airoha_eth *eth = qdma->eth; - int qdma_id = qdma - ð->qdma[0]; - int i; -@@ -2226,10 +2229,10 @@ static int airoha_dev_set_features(struc - if (!p) - continue; - -- if (p->qdma != qdma) -+ d = p->dev; -+ if (d->qdma != qdma) - continue; - -- d = p->dev; - if (d->dev == netdev) - continue; - -@@ -2246,8 +2249,7 @@ static netdev_tx_t airoha_dev_xmit(struc - struct net_device *netdev) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; -- struct airoha_qdma *qdma = port->qdma; -+ struct airoha_qdma *qdma = dev->qdma; - u32 nr_frags, tag, msg0, msg1, len; - struct airoha_queue_entry *e; - struct netdev_queue *txq; -@@ -2285,7 +2287,7 @@ static netdev_tx_t airoha_dev_xmit(struc - } - } - -- fport = airoha_get_fe_port(port); -+ fport = airoha_get_fe_port(dev); - msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | - FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); - -@@ -2388,8 +2390,7 @@ static void airoha_ethtool_get_drvinfo(s - struct ethtool_drvinfo *info) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; -- struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_eth *eth = dev->eth; - - strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); - strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); -@@ -2402,7 +2403,7 @@ static void airoha_ethtool_get_mac_stats - struct airoha_gdm_port *port = dev->port; - unsigned int start; - -- airoha_update_hw_stats(port); -+ airoha_update_hw_stats(dev); - do { - start = u64_stats_fetch_begin(&port->stats.syncp); - stats->FramesTransmittedOK = port->stats.tx_ok_pkts; -@@ -2442,7 +2443,7 @@ airoha_ethtool_get_rmon_stats(struct net - ARRAY_SIZE(hw_stats->rx_len) + 1); - - *ranges = airoha_ethtool_rmon_ranges; -- airoha_update_hw_stats(port); -+ airoha_update_hw_stats(dev); - do { - int i; - -@@ -2462,18 +2463,17 @@ static int airoha_qdma_set_chan_tx_sched - const u16 *weights, u8 n_weights) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - int i; - - for (i = 0; i < AIROHA_NUM_TX_RING; i++) -- airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel), -+ airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel), - TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i)); - - for (i = 0; i < n_weights; i++) { - u32 status; - int err; - -- airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG, -+ airoha_qdma_wr(dev->qdma, REG_TXWRR_WEIGHT_CFG, - TWRR_RW_CMD_MASK | - FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) | - FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) | -@@ -2481,13 +2481,12 @@ static int airoha_qdma_set_chan_tx_sched - err = read_poll_timeout(airoha_qdma_rr, status, - status & TWRR_RW_CMD_DONE, - USEC_PER_MSEC, 10 * USEC_PER_MSEC, -- true, port->qdma, -- REG_TXWRR_WEIGHT_CFG); -+ true, dev->qdma, REG_TXWRR_WEIGHT_CFG); - if (err) - return err; - } - -- airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3), -+ airoha_qdma_rmw(dev->qdma, REG_CHAN_QOS_MODE(channel >> 3), - CHAN_QOS_MODE_MASK(channel), - __field_prep(CHAN_QOS_MODE_MASK(channel), mode)); - -@@ -2553,9 +2552,9 @@ static int airoha_qdma_get_tx_ets_stats( - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; - -- u64 cpu_tx_packets = airoha_qdma_rr(port->qdma, -+ u64 cpu_tx_packets = airoha_qdma_rr(dev->qdma, - REG_CNTR_VAL(channel << 1)); -- u64 fwd_tx_packets = airoha_qdma_rr(port->qdma, -+ u64 fwd_tx_packets = airoha_qdma_rr(dev->qdma, - REG_CNTR_VAL((channel << 1) + 1)); - u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + - (fwd_tx_packets - port->fwd_tx_packets); -@@ -2819,17 +2818,16 @@ static int airoha_qdma_set_tx_rate_limit - u32 bucket_size) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - int i, err; - - for (i = 0; i <= TRTCM_PEAK_MODE; i++) { -- err = airoha_qdma_set_trtcm_config(port->qdma, channel, -+ err = airoha_qdma_set_trtcm_config(dev->qdma, channel, - REG_EGRESS_TRTCM_CFG, i, - !!rate, TRTCM_METER_MODE); - if (err) - return err; - -- err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel, -+ err = airoha_qdma_set_trtcm_token_bucket(dev->qdma, channel, - REG_EGRESS_TRTCM_CFG, - i, rate, bucket_size); - if (err) -@@ -2879,11 +2877,11 @@ static int airoha_tc_htb_alloc_leaf_queu - return 0; - } - --static int airoha_qdma_set_rx_meter(struct airoha_gdm_port *port, -+static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev, - u32 rate, u32 bucket_size, - enum trtcm_unit_type unit_type) - { -- struct airoha_qdma *qdma = port->qdma; -+ struct airoha_qdma *qdma = dev->qdma; - int i; - - for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) { -@@ -2962,7 +2960,6 @@ static int airoha_dev_tc_matchall(struct - { - enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT; - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - u32 rate = 0, bucket_size = 0; - - switch (f->command) { -@@ -2987,7 +2984,7 @@ static int airoha_dev_tc_matchall(struct - fallthrough; - } - case TC_CLSMATCHALL_DESTROY: -- return airoha_qdma_set_rx_meter(port, rate, bucket_size, -+ return airoha_qdma_set_rx_meter(dev, rate, bucket_size, - unit_type); - default: - return -EOPNOTSUPP; -@@ -2999,8 +2996,7 @@ static int airoha_dev_setup_tc_block_cb( - { - struct net_device *netdev = cb_priv; - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; -- struct airoha_eth *eth = port->qdma->eth; -+ struct airoha_eth *eth = dev->eth; - - if (!tc_can_offload(netdev)) - return -EOPNOTSUPP; -@@ -3235,7 +3231,7 @@ static void airoha_mac_link_up(struct ph - struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev, - phylink_config); - struct airoha_gdm_port *port = dev->port; -- struct airoha_qdma *qdma = port->qdma; -+ struct airoha_qdma *qdma = dev->qdma; - struct airoha_eth *eth = qdma->eth; - u32 frag_size_tx, frag_size_rx; - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -549,6 +549,7 @@ struct airoha_qdma { - - struct airoha_gdm_dev { - struct airoha_gdm_port *port; -+ struct airoha_qdma *qdma; - struct net_device *dev; - struct airoha_eth *eth; - -@@ -559,7 +560,6 @@ struct airoha_gdm_dev { - }; - - struct airoha_gdm_port { -- struct airoha_qdma *qdma; - struct airoha_gdm_dev *dev; - int id; - int nbq; -@@ -695,19 +695,18 @@ static inline bool airoha_qdma_is_lro_qu - return !!(AIROHA_RXQ_LRO_EN_MASK & BIT(qid)); - } - --int airoha_get_fe_port(struct airoha_gdm_port *port); -+int airoha_get_fe_port(struct airoha_gdm_dev *dev); - bool airoha_is_valid_gdm_dev(struct airoha_eth *eth, - struct airoha_gdm_dev *dev); - --void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, -- u8 fport); -+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport); - bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); - void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, - u16 hash, bool rx_wlan); - int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); --void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port); -+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev); - u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe); - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -85,9 +85,9 @@ static u32 airoha_ppe_get_timestamp(stru - AIROHA_FOE_IB1_BIND_TIMESTAMP); - } - --void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport) -+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport) - { -- struct airoha_qdma *qdma = port->qdma; -+ struct airoha_qdma *qdma = dev->qdma; - struct airoha_eth *eth = qdma->eth; - u8 qdma_id = qdma - ð->qdma[0]; - u32 fe_cpu_port; -@@ -181,8 +181,8 @@ static void airoha_ppe_hw_init(struct ai - if (!port) - continue; - -- airoha_ppe_set_cpu_port(port, i, -- airoha_get_fe_port(port)); -+ airoha_ppe_set_cpu_port(port->dev, i, -+ airoha_get_fe_port(port->dev)); - } - } - } -@@ -1483,11 +1483,12 @@ void airoha_ppe_check_skb(struct airoha_ - airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan); - } - --void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port) -+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev) - { -- struct airoha_eth *eth = port->qdma->eth; -- struct net_device *dev = port->dev->dev; -- const u8 *addr = dev->dev_addr; -+ struct airoha_gdm_port *port = dev->port; -+ struct net_device *netdev = dev->dev; -+ struct airoha_eth *eth = dev->eth; -+ const u8 *addr = netdev->dev_addr; - u32 val; - - val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; diff --git a/target/linux/airoha/patches-6.12/920-03-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch b/target/linux/airoha/patches-6.12/920-03-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch deleted file mode 100644 index dfcd606c4d6..00000000000 --- a/target/linux/airoha/patches-6.12/920-03-net-airoha-Rely-on-airoha_gdm_dev-pointer-in-airoha_.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 32bfd008c19f9ad55514181d8cd02e14bf384475 Mon Sep 17 00:00:00 2001 -Message-ID: <32bfd008c19f9ad55514181d8cd02e14bf384475.1779348625.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Sat, 13 Dec 2025 10:06:45 +0100 -Subject: [PATCH 03/13] net: airoha: Rely on airoha_gdm_dev pointer in - airoha_is_lan_gdm_port() - -Rename airoha_is_lan_gdm_port in airoha_is_lan_gdm_dev. Moreover, rely -on airoha_gdm_dev pointer in airoha_is_lan_gdm_dev() instead of -airoha_gdm_port one. -This is a preliminary patch to support multiple net_devices connected to -the same GDM{3,4} port via an external hw arbiter. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 6 ++---- - drivers/net/ethernet/airoha/airoha_eth.h | 4 +++- - drivers/net/ethernet/airoha/airoha_ppe.c | 2 +- - 3 files changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -82,12 +82,10 @@ static bool airhoa_is_phy_external(struc - - static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr) - { -- struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = dev->eth; - u32 val, reg; - -- reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H -- : REG_FE_WAN_MAC_H; -+ reg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H; - val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; - airoha_fe_wr(eth, reg, val); - -@@ -2038,7 +2036,7 @@ static int airoha_dev_init(struct net_de - int i; - - /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ -- dev->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)]; -+ dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)]; - dev->dev->irq = dev->qdma->irq_banks[0].irq; - airoha_set_macaddr(dev, netdev->dev_addr); - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -664,8 +664,10 @@ static inline u16 airoha_qdma_get_txq(st - return qid % ARRAY_SIZE(qdma->q_tx); - } - --static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port) -+static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev) - { -+ struct airoha_gdm_port *port = dev->port; -+ - /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. - * GDM{2,3,4} can be used as wan port connected to an external - * phy module. ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -365,7 +365,7 @@ static int airoha_ppe_foe_entry_prepare( - /* For downlink traffic consume SRAM memory for hw - * forwarding descriptors queue. - */ -- if (airoha_is_lan_gdm_port(port)) -+ if (airoha_is_lan_gdm_dev(dev)) - val |= AIROHA_FOE_IB2_FAST_PATH; - if (dsa_port >= 0) - val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, diff --git a/target/linux/airoha/patches-6.12/920-04-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch b/target/linux/airoha/patches-6.12/920-04-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch deleted file mode 100644 index 7e0077124ac..00000000000 --- a/target/linux/airoha/patches-6.12/920-04-net-airoha-Move-qos_sq_bmap-in-airoha_gdm_dev-struct.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 634d75285db77f3385aa85a1bf2b185396225100 Mon Sep 17 00:00:00 2001 -Message-ID: <634d75285db77f3385aa85a1bf2b185396225100.1779348625.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Fri, 10 Apr 2026 14:35:32 +0200 -Subject: [PATCH 04/13] net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct - -Since now multiple net_devices connected to different QDMA blocks can -share the same GDM port, qos_sq_bmap field can be overwritten with the -configuration obtained from a net_device connected to a different QDMA -block. In order to fix the issue move qos_sq_bmap field from -airoha_gdm_port struct to airoha_gdm_dev one. -Add qos_channel_map bitmap in airoha_qdma struct to track if a shared -QDMA channel is already in use by another net_device. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 58 +++++++++++++++--------- - drivers/net/ethernet/airoha/airoha_eth.h | 6 ++- - 2 files changed, 40 insertions(+), 24 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2835,30 +2835,40 @@ static int airoha_qdma_set_tx_rate_limit - return 0; - } - --static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev, -- struct tc_htb_qopt_offload *opt) -+static int airoha_tc_htb_modify_queue(struct net_device *dev, -+ struct tc_htb_qopt_offload *opt) - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; - u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */ -- int err, num_tx_queues = netdev->real_num_tx_queues; -- struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - - if (opt->parent_classid != TC_HTB_CLASSID_ROOT) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid"); - return -EINVAL; - } - -- err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate, -- opt->quantum); -- if (err) { -+ return airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum); -+} -+ -+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev, -+ struct tc_htb_qopt_offload *opt) -+{ -+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; -+ int err, num_tx_queues = netdev->real_num_tx_queues; -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_qdma *qdma = dev->qdma; -+ -+ /* Here we need to check the requested QDMA channel is not already -+ * in use by another net_device running on the same QDMA block. -+ */ -+ if (test_and_set_bit(channel, qdma->qos_channel_map)) { - NL_SET_ERR_MSG_MOD(opt->extack, -- "failed configuring htb offload"); -- return err; -+ "qdma qos channel already in use"); -+ return -EBUSY; - } - -- if (opt->command == TC_HTB_NODE_MODIFY) -- return 0; -+ err = airoha_tc_htb_modify_queue(netdev, opt); -+ if (err) -+ goto error; - - err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1); - if (err) { -@@ -2866,13 +2876,17 @@ static int airoha_tc_htb_alloc_leaf_queu - opt->quantum); - NL_SET_ERR_MSG_MOD(opt->extack, - "failed setting real_num_tx_queues"); -- return err; -+ goto error; - } - -- set_bit(channel, port->qos_sq_bmap); -+ set_bit(channel, dev->qos_sq_bmap); - opt->qid = AIROHA_NUM_TX_RING + channel; - - return 0; -+error: -+ clear_bit(channel, qdma->qos_channel_map); -+ -+ return err; - } - - static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev, -@@ -3053,11 +3067,13 @@ static int airoha_dev_setup_tc_block(str - static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; -+ struct airoha_qdma *qdma = dev->qdma; - - netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1); - airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0); -- clear_bit(queue, port->qos_sq_bmap); -+ -+ clear_bit(queue, qdma->qos_channel_map); -+ clear_bit(queue, dev->qos_sq_bmap); - } - - static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev, -@@ -3065,9 +3081,8 @@ static int airoha_tc_htb_delete_leaf_que - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - -- if (!test_bit(channel, port->qos_sq_bmap)) { -+ if (!test_bit(channel, dev->qos_sq_bmap)) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); - return -EINVAL; - } -@@ -3080,10 +3095,9 @@ static int airoha_tc_htb_delete_leaf_que - static int airoha_tc_htb_destroy(struct net_device *netdev) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - int q; - -- for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) -+ for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS) - airoha_tc_remove_htb_queue(netdev, q); - - return 0; -@@ -3094,9 +3108,8 @@ static int airoha_tc_get_htb_get_leaf_qu - { - u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS; - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - -- if (!test_bit(channel, port->qos_sq_bmap)) { -+ if (!test_bit(channel, dev->qos_sq_bmap)) { - NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id"); - return -EINVAL; - } -@@ -3115,6 +3128,7 @@ static int airoha_tc_setup_qdisc_htb(str - case TC_HTB_DESTROY: - return airoha_tc_htb_destroy(dev); - case TC_HTB_NODE_MODIFY: -+ return airoha_tc_htb_modify_queue(dev, opt); - case TC_HTB_LEAF_ALLOC_QUEUE: - return airoha_tc_htb_alloc_leaf_queue(dev, opt); - case TC_HTB_LEAF_DEL: ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -545,6 +545,8 @@ struct airoha_qdma { - - struct airoha_queue q_tx[AIROHA_NUM_TX_RING]; - struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; -+ -+ DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS); - }; - - struct airoha_gdm_dev { -@@ -557,6 +559,8 @@ struct airoha_gdm_dev { - struct phylink *phylink; - struct phylink_config phylink_config; - #endif -+ -+ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); - }; - - struct airoha_gdm_port { -@@ -566,8 +570,6 @@ struct airoha_gdm_port { - - struct airoha_hw_stats stats; - -- DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); -- - /* qos stats counters */ - u64 cpu_tx_packets; - u64 fwd_tx_packets; diff --git a/target/linux/airoha/patches-6.12/920-05-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch b/target/linux/airoha/patches-6.12/920-05-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch deleted file mode 100644 index 9522e36b71d..00000000000 --- a/target/linux/airoha/patches-6.12/920-05-net-airoha-Move-cpu-fwd-_tx_packets-in-airoha_gdm_de.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 00272dbf6a52241a21145631f22dc5f03891078b Mon Sep 17 00:00:00 2001 -Message-ID: <00272dbf6a52241a21145631f22dc5f03891078b.1779348625.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Fri, 10 Apr 2026 14:47:08 +0200 -Subject: [PATCH 05/13] net: airoha: Move {cpu,fwd}_tx_packets in - airoha_gdm_dev struct - -Since now multiple net_devices connected to different QDMA blocks can -share the same GDM port, cpu_tx_packets and fwd_tx_packets fields can -be overwritten with the value from a different QDMA block. In order to -fix the issue move cpu_tx_packets and fwd_tx_packets fields from -airoha_gdm_port struct to airoha_gdm_dev one. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 16 +++++++--------- - drivers/net/ethernet/airoha/airoha_eth.h | 7 +++---- - 2 files changed, 10 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2548,19 +2548,17 @@ static int airoha_qdma_get_tx_ets_stats( - struct tc_ets_qopt_offload *opt) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; -+ struct airoha_qdma *qdma = dev->qdma; - -- u64 cpu_tx_packets = airoha_qdma_rr(dev->qdma, -- REG_CNTR_VAL(channel << 1)); -- u64 fwd_tx_packets = airoha_qdma_rr(dev->qdma, -+ u64 cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1)); -+ u64 fwd_tx_packets = airoha_qdma_rr(qdma, - REG_CNTR_VAL((channel << 1) + 1)); -- u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) + -- (fwd_tx_packets - port->fwd_tx_packets); -+ u64 tx_packets = (cpu_tx_packets - dev->cpu_tx_packets) + -+ (fwd_tx_packets - dev->fwd_tx_packets); - - _bstats_update(opt->stats.bstats, 0, tx_packets); -- -- port->cpu_tx_packets = cpu_tx_packets; -- port->fwd_tx_packets = fwd_tx_packets; -+ dev->cpu_tx_packets = cpu_tx_packets; -+ dev->fwd_tx_packets = fwd_tx_packets; - - return 0; - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -561,6 +561,9 @@ struct airoha_gdm_dev { - #endif - - DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS); -+ /* qos stats counters */ -+ u64 cpu_tx_packets; -+ u64 fwd_tx_packets; - }; - - struct airoha_gdm_port { -@@ -570,10 +573,6 @@ struct airoha_gdm_port { - - struct airoha_hw_stats stats; - -- /* qos stats counters */ -- u64 cpu_tx_packets; -- u64 fwd_tx_packets; -- - struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; - }; - diff --git a/target/linux/airoha/patches-6.12/920-06-net-airoha-Support-multiple-net_devices-for-a-single.patch b/target/linux/airoha/patches-6.12/920-06-net-airoha-Support-multiple-net_devices-for-a-single.patch deleted file mode 100644 index 22f4d2920dc..00000000000 --- a/target/linux/airoha/patches-6.12/920-06-net-airoha-Support-multiple-net_devices-for-a-single.patch +++ /dev/null @@ -1,715 +0,0 @@ -From 8eb0a71bfbe92b6fbc668c5d9ebdcbf6523a89ad Mon Sep 17 00:00:00 2001 -Message-ID: <8eb0a71bfbe92b6fbc668c5d9ebdcbf6523a89ad.1779348625.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Sat, 1 Nov 2025 11:27:48 +0100 -Subject: [PATCH 06/13] net: airoha: Support multiple net_devices for a single - FE GDM port -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g. -Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw arbiter that -manages the traffic in a TDM manner. As a result multiple net_devices can -connect to the same GDM{3,4} port and there is a theoretical "1:n" -relation between GDM ports and net_devices. - - ┌─────────────────────────────────┐ - │ │ ┌──────┐ - │ P1 GDM1 ├────►MT7530│ - │ │ └──────┘ - │ │ ETH0 (DSA conduit) - │ │ - │ PSE/FE │ - │ │ - │ │ - │ │ ┌─────┐ - │ P0 CDM1 ├────►QDMA0│ - │ P4 P9 GDM4 │ └─────┘ - └──┬─────────────────────────┬────┘ - │ │ - ┌──▼──┐ ┌────▼────┐ - │ PPE │ │ ARB │ - └─────┘ └─┬─────┬─┘ - │ │ - ┌──▼──┐┌─▼───┐ - │ ETH ││ USB │ - └─────┘└─────┘ - ETH1 ETH2 - -Introduce support for multiple net_devices connected to the same Frame -Engine (FE) GDM port (GDM3 or GDM4) via an external hw arbiter. -Please note GDM1 or GDM2 does not support the connection with the external -arbiter. -Add get_dev_from_sport callback since EN7581 and AN7583 have different -logics for the net_device type connected to GDM3 or GDM4. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 274 +++++++++++++++++------ - drivers/net/ethernet/airoha/airoha_eth.h | 10 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 13 +- - 3 files changed, 228 insertions(+), 69 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -115,7 +115,7 @@ static int airoha_set_vip_for_gdm_port(s - struct airoha_eth *eth = dev->eth; - u32 vip_port; - -- vip_port = eth->soc->ops.get_vip_port(port, port->nbq); -+ vip_port = eth->soc->ops.get_vip_port(port, dev->nbq); - if (enable) { - airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); - airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); -@@ -619,30 +619,26 @@ static int airoha_qdma_fill_rx_queue(str - return nframes; - } - --static int airoha_qdma_get_gdm_port(struct airoha_eth *eth, -- struct airoha_qdma_desc *desc) -+static struct airoha_gdm_dev * -+airoha_qdma_get_gdm_dev(struct airoha_eth *eth, struct airoha_qdma_desc *desc) - { -- u32 port, sport, msg1 = le32_to_cpu(READ_ONCE(desc->msg1)); -+ struct airoha_gdm_port *port; -+ u16 p, d; - -- sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1); -- switch (sport) { -- case 0x18: -- port = 3; /* GDM4 */ -- break; -- case 0x16: -- port = 2; /* GDM3 */ -- break; -- case 0x10 ... 0x14: -- port = 0; /* GDM1 */ -- break; -- case 0x2 ... 0x4: -- port = sport - 1; -- break; -- default: -- return -EINVAL; -- } -+ if (eth->soc->ops.get_dev_from_sport(desc, &p, &d)) -+ return ERR_PTR(-ENODEV); -+ -+ if (p >= ARRAY_SIZE(eth->ports)) -+ return ERR_PTR(-ENODEV); -+ -+ port = eth->ports[p]; -+ if (!port) -+ return ERR_PTR(-ENODEV); -+ -+ if (d >= ARRAY_SIZE(port->devs)) -+ return ERR_PTR(-ENODEV); - -- return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port; -+ return port->devs[d] ? port->devs[d] : ERR_PTR(-ENODEV); - } - - static int airoha_qdma_lro_rx_process(struct airoha_queue *q, -@@ -736,9 +732,8 @@ static int airoha_qdma_rx_process(struct - struct airoha_queue_entry *e = &q->entry[q->tail]; - struct airoha_qdma_desc *desc = &q->desc[q->tail]; - u32 hash, reason, msg1, desc_ctrl; -- struct airoha_gdm_port *port; -- struct net_device *netdev; -- int data_len, len, p; -+ struct airoha_gdm_dev *dev; -+ int data_len, len; - struct page *page; - - desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl)); -@@ -759,15 +754,10 @@ static int airoha_qdma_rx_process(struct - if (!len || data_len < len) - goto free_frag; - -- p = airoha_qdma_get_gdm_port(eth, desc); -- if (p < 0 || !eth->ports[p]) -- goto free_frag; -- -- port = eth->ports[p]; -- if (!port->dev) -+ dev = airoha_qdma_get_gdm_dev(eth, desc); -+ if (IS_ERR(dev)) - goto free_frag; - -- netdev = port->dev->dev; - if (!q->skb) { /* first buffer */ - q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM, - q->buf_size); -@@ -776,14 +766,14 @@ static int airoha_qdma_rx_process(struct - - skb_reserve(q->skb, AIROHA_RX_HEADROOM); - __skb_put(q->skb, len); -- q->skb->dev = netdev; -+ q->skb->dev = dev->dev; - q->skb->ip_summed = CHECKSUM_UNNECESSARY; - skb_record_rx_queue(q->skb, qid); - - if (airoha_qdma_lro_rx_process(q, desc) < 0) - goto free_frag; - -- q->skb->protocol = eth_type_trans(q->skb, netdev); -+ q->skb->protocol = eth_type_trans(q->skb, dev->dev); - skb_mark_for_recycle(q->skb); - } else { /* scattered frame */ - struct skb_shared_info *shinfo = skb_shinfo(q->skb); -@@ -800,7 +790,9 @@ static int airoha_qdma_rx_process(struct - if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl)) - continue; - -- if (netdev_uses_dsa(netdev)) { -+ if (netdev_uses_dsa(dev->dev)) { -+ struct airoha_gdm_port *port = dev->port; -+ - /* PPE module requires untagged packets to work - * properly and it provides DSA port index via the - * DMA descriptor. Report DSA tag to the DSA stack -@@ -997,24 +989,27 @@ static void airoha_qdma_wake_netdev_txqs - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -- struct airoha_gdm_dev *dev; -- int j; -+ int d; - - if (!port) - continue; - -- dev = port->dev; -- if (!dev) -- continue; -+ for (d = 0; d < ARRAY_SIZE(port->devs); d++) { -+ struct airoha_gdm_dev *dev = port->devs[d]; -+ int j; - -- if (dev->qdma != qdma) -- continue; -+ if (!dev) -+ continue; - -- for (j = 0; j < dev->dev->num_tx_queues; j++) { -- if (airoha_qdma_get_txq(qdma, j) != qid) -+ if (dev->qdma != qdma) - continue; - -- netif_wake_subqueue(dev->dev, j); -+ for (j = 0; j < dev->dev->num_tx_queues; j++) { -+ if (airoha_qdma_get_txq(qdma, j) != qid) -+ continue; -+ -+ netif_wake_subqueue(dev->dev, j); -+ } - } - } - q->txq_stopped = false; -@@ -1903,11 +1898,9 @@ static int airoha_dev_open(struct net_de - GLOBAL_CFG_RX_DMA_EN_MASK); - atomic_inc(&qdma->users); - -- if (port->id == AIROHA_GDM2_IDX && -- airoha_ppe_is_enabled(qdma->eth, 1)) { -- /* For PPE2 always use secondary cpu port. */ -+ if (!airoha_is_lan_gdm_dev(dev) && -+ airoha_ppe_is_enabled(qdma->eth, 1)) - pse_port = FE_PSE_PORT_PPE2; -- } - airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id), - pse_port); - -@@ -2002,7 +1995,7 @@ static int airoha_set_gdm2_loopback(stru - airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); - airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX)); - -- src_port = eth->soc->ops.get_sport(port, port->nbq); -+ src_port = eth->soc->ops.get_sport(port, dev->nbq); - if (src_port < 0) - return src_port; - -@@ -2019,7 +2012,7 @@ static int airoha_set_gdm2_loopback(stru - airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX); - - if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) { -- u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq); -+ u32 mask = FC_ID_OF_SRC_PORT_MASK(dev->nbq); - - airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask, - __field_prep(mask, AIROHA_GDM2_IDX)); -@@ -2033,7 +2026,7 @@ static int airoha_dev_init(struct net_de - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = dev->eth; -- int i; -+ int ppe_id; - - /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ - dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)]; -@@ -2056,8 +2049,8 @@ static int airoha_dev_init(struct net_de - break; - } - -- for (i = 0; i < eth->soc->num_ppe; i++) -- airoha_ppe_set_cpu_port(dev, i, airoha_get_fe_port(dev)); -+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1); -+ airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev)); - - return 0; - } -@@ -2222,20 +2215,26 @@ static int airoha_dev_set_features(struc - } else { - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *p = eth->ports[i]; -- struct airoha_gdm_dev *d; -+ int j; - - if (!p) - continue; - -- d = p->dev; -- if (d->qdma != qdma) -- continue; -+ for (j = 0; j < ARRAY_SIZE(p->devs); j++) { -+ struct airoha_gdm_dev *d = p->devs[j]; - -- if (d->dev == netdev) -- continue; -+ if (!d) -+ continue; - -- if (d->dev->features & NETIF_F_LRO) -- return 0; -+ if (d->qdma != qdma) -+ continue; -+ -+ if (d->dev == netdev) -+ continue; -+ -+ if (d->dev->features & NETIF_F_LRO) -+ return 0; -+ } - } - airoha_fe_lro_disable(eth, qdma_id); - } -@@ -2286,7 +2285,8 @@ static netdev_tx_t airoha_dev_xmit(struc - } - - fport = airoha_get_fe_port(dev); -- msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | -+ msg1 = FIELD_PREP(QDMA_ETH_TXMSG_NBOQ_MASK, dev->nbq) | -+ FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) | - FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f); - - q = &qdma->q_tx[qid]; -@@ -3222,12 +3222,15 @@ bool airoha_is_valid_gdm_dev(struct airo - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -+ int j; - - if (!port) - continue; - -- if (port->dev == dev) -- return true; -+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) { -+ if (port->devs[j] == dev) -+ return true; -+ } - } - - return false; -@@ -3351,10 +3354,11 @@ static int airoha_setup_phylink(struct n - - static int airoha_alloc_gdm_device(struct airoha_eth *eth, - struct airoha_gdm_port *port, -- struct device_node *np) -+ int nbq, struct device_node *np) - { -- struct airoha_gdm_dev *dev; - struct net_device *netdev; -+ struct airoha_gdm_dev *dev; -+ u8 index; - int err; - - netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev), -@@ -3372,7 +3376,6 @@ static int airoha_alloc_gdm_device(struc - netdev->hw_features = AIROHA_HW_FEATURES | NETIF_F_LRO; - netdev->features |= AIROHA_HW_FEATURES; - netdev->vlan_features = AIROHA_HW_FEATURES; -- netdev->dev.of_node = np; - SET_NETDEV_DEV(netdev, eth->dev); - - /* reserve hw queues for HTB offloading */ -@@ -3390,11 +3393,25 @@ static int airoha_alloc_gdm_device(struc - netdev->dev_addr); - } - -+ /* Allowed nbq for EN7581 on GDM3 port are 4 and 5 for PCIE0 -+ * and PCIE1 respectively. -+ */ -+ index = nbq; -+ if (index && airoha_is_7581(eth) && port->id == AIROHA_GDM3_IDX) -+ index -= 4; -+ -+ if (index >= ARRAY_SIZE(port->devs) || port->devs[index]) { -+ dev_err(eth->dev, "invalid nbq id: %d\n", nbq); -+ return -EINVAL; -+ } -+ -+ netdev->dev.of_node = of_node_get(np); - dev = netdev_priv(netdev); - dev->dev = netdev; - dev->port = port; -- port->dev = dev; - dev->eth = eth; -+ dev->nbq = nbq; -+ port->devs[index] = dev; - - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { -@@ -3412,7 +3429,8 @@ static int airoha_alloc_gdm_port(struct - { - const __be32 *id_ptr = of_get_property(np, "reg", NULL); - struct airoha_gdm_port *port; -- int err, p; -+ struct device_node *node; -+ int err, nbq, p, d = 0; - u32 id; - - if (!id_ptr) { -@@ -3440,15 +3458,51 @@ static int airoha_alloc_gdm_port(struct - u64_stats_init(&port->stats.syncp); - spin_lock_init(&port->stats.lock); - port->id = id; -- /* XXX: Read nbq from DTS */ -- port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; - eth->ports[p] = port; - - err = airoha_metadata_dst_alloc(port); - if (err) - return err; - -- return airoha_alloc_gdm_device(eth, port, np); -+ /* Default nbq value to ensure backward compatibility */ -+ nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; -+ -+ for_each_child_of_node(np, node) { -+ /* Multiple external serdes connected to the FE GDM port via an -+ * external arbiter. -+ */ -+ const __be32 *nbq_ptr; -+ -+ if (!of_device_is_compatible(node, "airoha,eth-port")) -+ continue; -+ -+ d++; -+ if (!of_device_is_available(node)) -+ continue; -+ -+ nbq_ptr = of_get_property(node, "reg", NULL); -+ if (!nbq_ptr) { -+ dev_err(eth->dev, "missing nbq id\n"); -+ of_node_put(node); -+ return -EINVAL; -+ } -+ -+ /* Verify the provided nbq parameter is valid */ -+ nbq = be32_to_cpup(nbq_ptr); -+ err = eth->soc->ops.get_sport(port, nbq); -+ if (err < 0) { -+ of_node_put(node); -+ return err; -+ } -+ -+ err = airoha_alloc_gdm_device(eth, port, nbq, node); -+ if (err) { -+ of_node_put(node); -+ return err; -+ } -+ } -+ -+ return !d ? airoha_alloc_gdm_device(eth, port, nbq, np) : 0; - } - - static int airoha_register_gdm_devices(struct airoha_eth *eth) -@@ -3457,14 +3511,22 @@ static int airoha_register_gdm_devices(s - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -- int err; -+ int j; - - if (!port) - continue; - -- err = register_netdev(port->dev->dev); -- if (err) -- return err; -+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) { -+ struct airoha_gdm_dev *dev = port->devs[j]; -+ int err; -+ -+ if (!dev) -+ continue; -+ -+ err = register_netdev(dev->dev); -+ if (err) -+ return err; -+ } - } - - set_bit(DEV_STATE_REGISTERED, ð->state); -@@ -3571,18 +3633,27 @@ error_napi_stop: - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -- struct airoha_gdm_dev *dev; -+ int j; - - if (!port) - continue; - -- dev = port->dev; -- if (dev && dev->dev->reg_state == NETREG_REGISTERED) { -+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) { -+ struct airoha_gdm_dev *dev = port->devs[j]; -+ struct net_device *netdev; -+ -+ if (!dev) -+ continue; -+ -+ netdev = dev->dev; -+ if (netdev->reg_state == NETREG_REGISTERED) { - #if defined(CONFIG_PCS_AIROHA) -- if (airhoa_is_phy_external(port)) -- phylink_destroy(dev->phylink); -+ if (airhoa_is_phy_external(port)) -+ phylink_destroy(dev->phylink); - #endif -- unregister_netdev(dev->dev); -+ unregister_netdev(netdev); -+ } -+ of_node_put(netdev->dev.of_node); - } - airoha_metadata_dst_free(port); - } -@@ -3604,19 +3675,26 @@ static void airoha_remove(struct platfor - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { - struct airoha_gdm_port *port = eth->ports[i]; -- struct airoha_gdm_dev *dev; -+ int j; - - if (!port) - continue; - -+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) { -+ struct airoha_gdm_dev *dev = port->devs[j]; -+ struct net_device *netdev; -+ -+ if (!dev) -+ continue; -+ - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) - phylink_destroy(dev->phylink); - #endif -- -- dev = port->dev; -- if (dev) -- unregister_netdev(dev->dev); -+ netdev = dev->dev; -+ unregister_netdev(netdev); -+ of_node_put(netdev->dev.of_node); -+ } - airoha_metadata_dst_free(port); - } - airoha_hw_cleanup(eth); -@@ -3678,6 +3756,39 @@ static u32 airoha_en7581_get_vip_port(st - return 0; - } - -+static int airoha_en7581_get_dev_from_sport(struct airoha_qdma_desc *desc, -+ u16 *port, u16 *dev) -+{ -+ u32 sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, -+ le32_to_cpu(READ_ONCE(desc->msg1))); -+ -+ *dev = 0; -+ switch (sport) { -+ case 0x10 ... 0x14: -+ *port = 0; /* GDM1 */ -+ break; -+ case 0x2 ... 0x4: -+ *port = sport - 1; -+ break; -+ case HSGMII_LAN_7581_PCIE1_SRCPORT: -+ *dev = 1; -+ fallthrough; -+ case HSGMII_LAN_7581_PCIE0_SRCPORT: -+ *port = 2; /* GDM3 */ -+ break; -+ case HSGMII_LAN_7581_USB_SRCPORT: -+ *dev = 1; -+ fallthrough; -+ case HSGMII_LAN_7581_ETH_SRCPORT: -+ *port = 3; /* GDM4 */ -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static const char * const an7583_xsi_rsts_names[] = { - "hsi0-mac", - "hsi1-mac", -@@ -3726,6 +3837,36 @@ static u32 airoha_an7583_get_vip_port(st - return 0; - } - -+static int airoha_an7583_get_dev_from_sport(struct airoha_qdma_desc *desc, -+ u16 *port, u16 *dev) -+{ -+ u32 sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, -+ le32_to_cpu(READ_ONCE(desc->msg1))); -+ -+ *dev = 0; -+ switch (sport) { -+ case 0x10 ... 0x14: -+ *port = 0; /* GDM1 */ -+ break; -+ case 0x2 ... 0x4: -+ *port = sport - 1; -+ break; -+ case HSGMII_LAN_7583_ETH_SRCPORT: -+ *port = 2; /* GDM3 */ -+ break; -+ case HSGMII_LAN_7583_USB_SRCPORT: -+ *dev = 1; -+ fallthrough; -+ case HSGMII_LAN_7583_PCIE_SRCPORT: -+ *port = 3; /* GDM4 */ -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static const struct airoha_eth_soc_data en7581_soc_data = { - .version = 0x7581, - .xsi_rsts_names = en7581_xsi_rsts_names, -@@ -3734,6 +3875,7 @@ static const struct airoha_eth_soc_data - .ops = { - .get_sport = airoha_en7581_get_sport, - .get_vip_port = airoha_en7581_get_vip_port, -+ .get_dev_from_sport = airoha_en7581_get_dev_from_sport, - }, - }; - -@@ -3745,6 +3887,7 @@ static const struct airoha_eth_soc_data - .ops = { - .get_sport = airoha_an7583_get_sport, - .get_vip_port = airoha_an7583_get_vip_port, -+ .get_dev_from_sport = airoha_an7583_get_dev_from_sport, - }, - }; - ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -17,6 +17,7 @@ - #include - - #define AIROHA_MAX_NUM_GDM_PORTS 4 -+#define AIROHA_MAX_NUM_GDM_DEVS 2 - #define AIROHA_MAX_NUM_QDMA 2 - #define AIROHA_MAX_NUM_IRQ_BANKS 4 - #define AIROHA_MAX_DSA_PORTS 7 -@@ -552,8 +553,8 @@ struct airoha_qdma { - struct airoha_gdm_dev { - struct airoha_gdm_port *port; - struct airoha_qdma *qdma; -- struct net_device *dev; - struct airoha_eth *eth; -+ struct net_device *dev; - - #if defined(CONFIG_PCS_AIROHA) - struct phylink *phylink; -@@ -564,12 +565,13 @@ struct airoha_gdm_dev { - /* qos stats counters */ - u64 cpu_tx_packets; - u64 fwd_tx_packets; -+ -+ int nbq; - }; - - struct airoha_gdm_port { -- struct airoha_gdm_dev *dev; -+ struct airoha_gdm_dev *devs[AIROHA_MAX_NUM_GDM_DEVS]; - int id; -- int nbq; - - struct airoha_hw_stats stats; - -@@ -605,6 +607,8 @@ struct airoha_eth_soc_data { - struct { - int (*get_sport)(struct airoha_gdm_port *port, int nbq); - u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq); -+ int (*get_dev_from_sport)(struct airoha_qdma_desc *desc, -+ u16 *port, u16 *dev); - } ops; - }; - ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -168,9 +168,7 @@ static void airoha_ppe_hw_init(struct ai - airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i), - PPE_FLOW_CFG_IP6_6RD_MASK); - -- for (p = 0; p < ARRAY_SIZE(eth->ports); p++) { -- struct airoha_gdm_port *port = eth->ports[p]; -- -+ for (p = 0; p < ARRAY_SIZE(eth->ports); p++) - airoha_fe_rmw(eth, REG_PPE_MTU(i, p), - FP0_EGRESS_MTU_MASK | - FP1_EGRESS_MTU_MASK, -@@ -178,11 +176,27 @@ static void airoha_ppe_hw_init(struct ai - AIROHA_MAX_MTU) | - FIELD_PREP(FP1_EGRESS_MTU_MASK, - AIROHA_MAX_MTU)); -- if (!port) -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *port = eth->ports[i]; -+ int j; -+ -+ if (!port) -+ continue; -+ -+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) { -+ struct airoha_gdm_dev *dev = port->devs[j]; -+ int ppe_id; -+ u8 fport; -+ -+ if (!dev) - continue; - -- airoha_ppe_set_cpu_port(port->dev, i, -- airoha_get_fe_port(port->dev)); -+ ppe_id = !airoha_is_lan_gdm_dev(dev) && -+ airoha_ppe_is_enabled(eth, 1); -+ fport = airoha_get_fe_port(dev); -+ airoha_ppe_set_cpu_port(dev, ppe_id, fport); - } - } - } diff --git a/target/linux/airoha/patches-6.12/920-07-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch b/target/linux/airoha/patches-6.12/920-07-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch deleted file mode 100644 index eafefba314a..00000000000 --- a/target/linux/airoha/patches-6.12/920-07-net-airoha-Do-not-stop-GDM-port-if-it-is-shared.patch +++ /dev/null @@ -1,132 +0,0 @@ -From de856a5b802cf030c8e242e98df3bc88446a4ea1 Mon Sep 17 00:00:00 2001 -Message-ID: -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Fri, 20 Mar 2026 11:09:40 +0100 -Subject: [PATCH 07/13] net: airoha: Do not stop GDM port if it is shared - -Theoretically, in the current codebase, two independent net_devices can -be connected to the same GDM port so we need to check the GDM port is not -used by any other running net_device before setting the forward -configuration to FE_PSE_PORT_DROP. -Moreover, always set in GDM_LONG_LEN_MASK field of REG_GDM_LEN_CFG -register the maximum MTU of all running net_devices connected to the same -GDM port. - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 59 +++++++++++++++++++----- - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - 2 files changed, 48 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1859,8 +1859,8 @@ static int airoha_dev_open(struct net_de - int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN; - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; -+ u32 cur_len, pse_port = FE_PSE_PORT_PPE1; - struct airoha_qdma *qdma = dev->qdma; -- u32 pse_port = FE_PSE_PORT_PPE1; - - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { -@@ -1888,10 +1888,20 @@ static int airoha_dev_open(struct net_de - airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), - GDM_STAG_EN_MASK); - -- airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id), -- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -- FIELD_PREP(GDM_LONG_LEN_MASK, len)); -+ cur_len = airoha_fe_get(qdma->eth, REG_GDM_LEN_CFG(port->id), -+ GDM_LONG_LEN_MASK); -+ if (!port->users || len > cur_len) { -+ /* Opening a sibling net_device with a larger MTU updates the -+ * MTU of already running devices. This is required to allow -+ * multiple net_devices with different MTUs to share the same -+ * GDM port. -+ */ -+ airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id), -+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -+ FIELD_PREP(GDM_LONG_LEN_MASK, len)); -+ } -+ port->users++; - - airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, - GLOBAL_CFG_TX_DMA_EN_MASK | -@@ -1907,6 +1917,30 @@ static int airoha_dev_open(struct net_de - return 0; - } - -+static void airoha_set_port_mtu(struct airoha_eth *eth, -+ struct airoha_gdm_port *port) -+{ -+ u32 len = 0; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) { -+ struct airoha_gdm_dev *dev = port->devs[i]; -+ struct net_device *netdev; -+ -+ if (!dev) -+ continue; -+ -+ netdev = dev->dev; -+ if (netif_running(netdev)) -+ len = max_t(u32, len, netdev->mtu); -+ } -+ len += ETH_HLEN + ETH_FCS_LEN; -+ -+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), -+ GDM_LONG_LEN_MASK, -+ FIELD_PREP(GDM_LONG_LEN_MASK, len)); -+} -+ - static int airoha_dev_stop(struct net_device *netdev) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -@@ -1919,8 +1953,12 @@ static int airoha_dev_stop(struct net_de - for (i = 0; i < netdev->num_tx_queues; i++) - netdev_tx_reset_subqueue(netdev, i); - -- airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id), -- FE_PSE_PORT_DROP); -+ if (--port->users) -+ airoha_set_port_mtu(dev->eth, port); -+ else -+ airoha_set_gdm_port_fwd_cfg(qdma->eth, -+ REG_GDM_FWD_CFG(port->id), -+ FE_PSE_PORT_DROP); - - if (atomic_dec_and_test(&qdma->users)) { - airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG, -@@ -2082,13 +2120,10 @@ static int airoha_dev_change_mtu(struct - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; -- u32 len = ETH_HLEN + mtu + ETH_FCS_LEN; -- struct airoha_eth *eth = dev->eth; - -- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), -- GDM_LONG_LEN_MASK, -- FIELD_PREP(GDM_LONG_LEN_MASK, len)); - WRITE_ONCE(netdev->mtu, mtu); -+ if (port->users) -+ airoha_set_port_mtu(dev->eth, port); - - return 0; - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -572,6 +572,7 @@ struct airoha_gdm_dev { - struct airoha_gdm_port { - struct airoha_gdm_dev *devs[AIROHA_MAX_NUM_GDM_DEVS]; - int id; -+ int users; - - struct airoha_hw_stats stats; - diff --git a/target/linux/airoha/patches-6.12/920-08-net-airoha-Introduce-WAN-device-flag.patch b/target/linux/airoha/patches-6.12/920-08-net-airoha-Introduce-WAN-device-flag.patch deleted file mode 100644 index bb9145c2280..00000000000 --- a/target/linux/airoha/patches-6.12/920-08-net-airoha-Introduce-WAN-device-flag.patch +++ /dev/null @@ -1,174 +0,0 @@ -From c4f3077948eda05a6b9d1a11304d82c3e0300151 Mon Sep 17 00:00:00 2001 -Message-ID: -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Fri, 3 Apr 2026 12:07:27 +0200 -Subject: [PATCH 08/13] net: airoha: Introduce WAN device flag - -Introduce WAN flag to specify if a given device is used to transmit/receive -WAN or LAN traffic. Current codebase supports specifying LAN/WAN device -configuration in ndo_init() callback during device bootstrap. -In order to consider setups where LAN configuration is used even for -GDM3/GDM4 devices, check airoha_is_lan_gdm_dev() to select pse_port in -airoha_ppe_foe_entry_prepare(). -Please note after this patch, it will be possible to specify multiple LAN -devices but just a single WAN one. Please note this change is not visible -to the user since airoha_eth driver currently supports just the internal -phy available via the MT7530 DSA switch and there are no WAN interfaces -officially supported since PCS/external phy is not merged mainline yet -(it will be posted with following patches). - -Tested-by: Xuegang Lu -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 72 +++++++++++++++++++----- - drivers/net/ethernet/airoha/airoha_eth.h | 13 ++--- - drivers/net/ethernet/airoha/airoha_ppe.c | 2 +- - 3 files changed, 65 insertions(+), 22 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2059,36 +2059,80 @@ static int airoha_set_gdm2_loopback(stru - return 0; - } - --static int airoha_dev_init(struct net_device *netdev) -+static struct airoha_gdm_dev * -+airoha_get_wan_gdm_dev(struct airoha_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *port = eth->ports[i]; -+ int j; -+ -+ if (!port) -+ continue; -+ -+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) { -+ struct airoha_gdm_dev *dev = port->devs[j]; -+ -+ if (dev && !airoha_is_lan_gdm_dev(dev)) -+ return dev; -+ } -+ } -+ -+ return NULL; -+} -+ -+static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev) - { -- struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = dev->eth; - int ppe_id; - - /* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */ - dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)]; - dev->dev->irq = dev->qdma->irq_banks[0].irq; -- airoha_set_macaddr(dev, netdev->dev_addr); -+ -+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1); -+ airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev)); -+} -+ -+static int airoha_dev_init(struct net_device *netdev) -+{ -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; - - switch (port->id) { - case AIROHA_GDM3_IDX: -- case AIROHA_GDM4_IDX: -- /* If GDM2 is active we can't enable loopback */ -- if (!eth->ports[1]) { -- int err; -- -- err = airoha_set_gdm2_loopback(dev); -- if (err) -- return err; -- } -+ case AIROHA_GDM4_IDX: { -+ struct airoha_eth *eth = dev->eth; -+ -+ /* GDM2 supports a single net_device */ -+ if (eth->ports[1] && eth->ports[1]->devs[0]) -+ break; -+ -+ if (airoha_get_wan_gdm_dev(eth)) -+ break; -+ -+ fallthrough; -+ } -+ case AIROHA_GDM2_IDX: -+ /* GDM2 is always used as wan */ -+ dev->flags |= AIROHA_PRIV_F_WAN; - break; - default: - break; - } - -- ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1); -- airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev)); -+ airoha_dev_set_qdma(dev); -+ airoha_set_macaddr(dev, netdev->dev_addr); -+ -+ if (!airoha_is_lan_gdm_dev(dev) && -+ (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) { -+ int err; -+ -+ err = airoha_set_gdm2_loopback(dev); -+ if (err) -+ return err; -+ } - - return 0; - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -550,6 +550,10 @@ struct airoha_qdma { - DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS); - }; - -+enum airoha_priv_flags { -+ AIROHA_PRIV_F_WAN = BIT(0), -+}; -+ - struct airoha_gdm_dev { - struct airoha_gdm_port *port; - struct airoha_qdma *qdma; -@@ -566,6 +570,7 @@ struct airoha_gdm_dev { - u64 cpu_tx_packets; - u64 fwd_tx_packets; - -+ u32 flags; - int nbq; - }; - -@@ -672,13 +677,7 @@ static inline u16 airoha_qdma_get_txq(st - - static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev) - { -- struct airoha_gdm_port *port = dev->port; -- -- /* GDM1 port on EN7581 SoC is connected to the lan dsa switch. -- * GDM{2,3,4} can be used as wan port connected to an external -- * phy module. -- */ -- return port->id == 1; -+ return !(dev->flags & AIROHA_PRIV_F_WAN); - } - - static inline bool airoha_is_7581(struct airoha_eth *eth) ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -354,7 +354,7 @@ static int airoha_ppe_foe_entry_prepare( - return -EINVAL; - - port = dev->port; -- if (dsa_port >= 0 || eth->ports[1]) -+ if (dsa_port >= 0 || airoha_is_lan_gdm_dev(dev)) - pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 - : port->id; - else diff --git a/target/linux/airoha/patches-6.12/920-09-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch b/target/linux/airoha/patches-6.12/920-09-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch deleted file mode 100644 index d60794e1b75..00000000000 --- a/target/linux/airoha/patches-6.12/920-09-net-airoha-Support-multiple-LAN-WAN-interfaces-for-h.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 144f0e6e55896625e3411aad02399a5ebb48d8f9 Mon Sep 17 00:00:00 2001 -Message-ID: <144f0e6e55896625e3411aad02399a5ebb48d8f9.1779348625.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Mon, 13 Apr 2026 17:38:51 +0200 -Subject: [PATCH 09/13] net: airoha: Support multiple LAN/WAN interfaces for hw - MAC address configuration - -The EN7581 and AN7583 SoCs provide registers to configure hardware LAN/WAN -MAC addresses, used to determine whether received traffic is destined for -this host or should be forwarded to another device. -The SoC hardware design assumes all interfaces configured as LAN (or WAN) -share a common upper MAC address, which is programmed into the -REG_FE_{LAN,WAN}_MAC_H register. The lower bytes of 'local' addresses can -be expressed as a range via the REG_FE_MAC_LMIN and REG_FE_MAC_LMAX -registers. -Previously, only a single interface was considered when programming these -registers. Extend the logic to derive the correct minimum and maximum -values for REG_FE_MAC_LMIN/REG_FE_MAC_LMAX when two or more interfaces are -configured as LAN or WAN. - -Tested-by: Madhur Agrawal -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 77 ++++++++++++++++++++---- - drivers/net/ethernet/airoha/airoha_eth.h | 2 +- - drivers/net/ethernet/airoha/airoha_ppe.c | 4 +- - 3 files changed, 68 insertions(+), 15 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -80,20 +80,74 @@ static bool airhoa_is_phy_external(struc - } - #endif - --static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr) -+static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr) - { -+ u8 ref_addr[ETH_ALEN] __aligned(2); - struct airoha_eth *eth = dev->eth; -- u32 val, reg; -+ u32 reg, val, lmin, lmax; -+ int i; -+ -+ eth_zero_addr(ref_addr); -+ lmin = (addr[3] << 16) | (addr[4] << 8) | addr[5]; -+ lmax = lmin; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -+ struct airoha_gdm_port *port = eth->ports[i]; -+ int j; -+ -+ if (!port) -+ continue; -+ -+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) { -+ struct airoha_gdm_dev *iter_dev; -+ struct net_device *netdev; -+ -+ iter_dev = port->devs[j]; -+ if (!iter_dev || iter_dev == dev) -+ continue; -+ -+ if (airoha_is_lan_gdm_dev(iter_dev) != -+ airoha_is_lan_gdm_dev(dev)) -+ continue; -+ -+ netdev = iter_dev->dev; -+ if (netdev->reg_state != NETREG_REGISTERED) -+ continue; -+ -+ ether_addr_copy(ref_addr, netdev->dev_addr); -+ val = (netdev->dev_addr[3] << 16) | -+ (netdev->dev_addr[4] << 8) | netdev->dev_addr[5]; -+ if (val < lmin) -+ lmin = val; -+ if (val > lmax) -+ lmax = val; -+ } -+ } -+ -+ if (!is_zero_ether_addr(ref_addr) && memcmp(ref_addr, addr, 3)) { -+ /* According to the HW design, hw mac address MSBs must be -+ * the same for each net_device with the same LAN/WAN -+ * configuration. -+ */ -+ dev_warn(eth->dev, -+ "%s: wrong mac addr, MSBs must be %02x:%02x:%02x\n", -+ dev->dev->name, ref_addr[0], ref_addr[1], -+ ref_addr[2]); -+ dev_warn(eth->dev, "FE hw forwarding won't work properly\n"); -+ -+ return -EINVAL; -+ } - - reg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H; - val = (addr[0] << 16) | (addr[1] << 8) | addr[2]; - airoha_fe_wr(eth, reg, val); - -- val = (addr[3] << 16) | (addr[4] << 8) | addr[5]; -- airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val); -- airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val); -+ airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), lmin); -+ airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), lmax); - -- airoha_ppe_init_upd_mem(dev); -+ airoha_ppe_init_upd_mem(dev, addr); -+ -+ return 0; - } - - static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr, -@@ -1986,13 +2040,18 @@ static int airoha_dev_stop(struct net_de - static int airoha_dev_set_macaddr(struct net_device *netdev, void *p) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct sockaddr *addr = p; - int err; - -- err = eth_mac_addr(netdev, p); -+ err = eth_prepare_mac_addr_change(netdev, p); -+ if (err) -+ return err; -+ -+ err = airoha_set_macaddr(dev, addr->sa_data); - if (err) - return err; - -- airoha_set_macaddr(dev, netdev->dev_addr); -+ eth_commit_mac_addr_change(netdev, p); - - return 0; - } ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -713,7 +713,7 @@ void airoha_ppe_check_skb(struct airoha_ - int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data); - int airoha_ppe_init(struct airoha_eth *eth); - void airoha_ppe_deinit(struct airoha_eth *eth); --void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev); -+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr); - u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe); - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash); ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -1497,12 +1497,10 @@ void airoha_ppe_check_skb(struct airoha_ - airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan); - } - --void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev) -+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr) - { - struct airoha_gdm_port *port = dev->port; -- struct net_device *netdev = dev->dev; - struct airoha_eth *eth = dev->eth; -- const u8 *addr = netdev->dev_addr; - u32 val; - - val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; diff --git a/target/linux/airoha/patches-6.12/920-10-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch b/target/linux/airoha/patches-6.12/920-10-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch deleted file mode 100644 index aca2ae25764..00000000000 --- a/target/linux/airoha/patches-6.12/920-10-net-airoha-Rename-airoha_set_gdm2_loopback-in-airoha.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 917f959d54efd09719bd5047aa4b9543615e131e Mon Sep 17 00:00:00 2001 -Message-ID: <917f959d54efd09719bd5047aa4b9543615e131e.1779348625.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Fri, 19 Dec 2025 23:12:32 +0100 -Subject: [PATCH 10/13] net: airoha: Rename airoha_set_gdm2_loopback in - airoha_enable_gdm2_loopback - -This is a preliminary patch in order to allow the user to select if the -configured device will be used as hw lan or wan. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2056,7 +2056,7 @@ static int airoha_dev_set_macaddr(struct - return 0; - } - --static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev) -+static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev) - { - struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = dev->eth; -@@ -2188,7 +2188,7 @@ static int airoha_dev_init(struct net_de - (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) { - int err; - -- err = airoha_set_gdm2_loopback(dev); -+ err = airoha_enable_gdm2_loopback(dev); - if (err) - return err; - } diff --git a/target/linux/airoha/patches-6.12/920-12-net-airoha-Add-ethtool-priv_flags-callbacks.patch b/target/linux/airoha/patches-6.12/920-12-net-airoha-Add-ethtool-priv_flags-callbacks.patch deleted file mode 100644 index f55b97253f3..00000000000 --- a/target/linux/airoha/patches-6.12/920-12-net-airoha-Add-ethtool-priv_flags-callbacks.patch +++ /dev/null @@ -1,246 +0,0 @@ -From e928621a0bbd010b75624c77105ce31f2b8d2faf Mon Sep 17 00:00:00 2001 -Message-ID: -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Sat, 13 Dec 2025 09:45:09 +0100 -Subject: [PATCH 12/13] net: airoha: Add ethtool priv_flags callbacks - -Introduce ethtool priv_flags callbacks in order to allow the user to -select if the configured device will be used as hw lan or wan and enable -or disable gdm2 loopback (used for hw QoS). - -Tested-by: Madhur Agrawal -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 173 ++++++++++++++++++++++ - drivers/net/ethernet/airoha/airoha_regs.h | 1 + - 2 files changed, 174 insertions(+) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -1916,6 +1916,11 @@ static int airoha_dev_open(struct net_de - u32 cur_len, pse_port = FE_PSE_PORT_PPE1; - struct airoha_qdma *qdma = dev->qdma; - -+ if (port->id == AIROHA_GDM2_IDX && airoha_is_lan_gdm_dev(dev)) { -+ /* GDM2 can be used just as wan */ -+ return -EBUSY; -+ } -+ - #if defined(CONFIG_PCS_AIROHA) - if (airhoa_is_phy_external(port)) { - err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0); -@@ -2118,6 +2123,45 @@ static int airoha_enable_gdm2_loopback(s - return 0; - } - -+static int airoha_disable_gdm2_loopback(struct airoha_gdm_dev *dev) -+{ -+ struct airoha_eth *eth = dev->eth; -+ int i, src_port; -+ u32 pse_port; -+ -+ src_port = eth->soc->ops.get_sport(dev->port, dev->nbq); -+ if (src_port < 0) -+ return src_port; -+ -+ airoha_fe_clear(eth, -+ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)), -+ SP_CPORT_MASK(src_port & SP_CPORT_DFT_MASK)); -+ -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), -+ FE_PSE_PORT_DROP); -+ airoha_fe_clear(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX), -+ LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK); -+ pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2 -+ : FE_PSE_PORT_PPE1; -+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), -+ pse_port); -+ -+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, WAN0_MASK, -+ FIELD_PREP(WAN0_MASK, AIROHA_GDM2_IDX)); -+ -+ for (i = 0; i < eth->soc->num_ppe; i++) -+ airoha_fe_clear(eth, REG_PPE_DFT_CPORT(i, AIROHA_GDM2_IDX), -+ DFT_CPORT_MASK(AIROHA_GDM2_IDX)); -+ -+ /* Enable VIP and IFC for GDM2 */ -+ airoha_fe_set(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); -+ airoha_fe_set(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX)); -+ -+ airoha_fe_wr(eth, REG_SRC_PORT_FC_MAP6, FC_MAP6_DEF_VALUE); -+ -+ return 0; -+} -+ - static struct airoha_gdm_dev * - airoha_get_wan_gdm_dev(struct airoha_eth *eth) - { -@@ -2522,6 +2566,80 @@ error: - return NETDEV_TX_OK; - } - -+struct airoha_ethool_priv_flags { -+ char name[ETH_GSTRING_LEN]; -+ int (*handler)(struct net_device *netdev, u32 flags); -+}; -+ -+static int airoha_dev_set_wan_flag(struct net_device *netdev, u32 flags) -+{ -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; -+ -+ if (!((dev->flags ^ flags) & AIROHA_PRIV_F_WAN)) -+ return 0; -+ -+ if (netif_running(netdev)) -+ return -EBUSY; -+ -+ if (flags & AIROHA_PRIV_F_WAN) { -+ struct airoha_gdm_dev *wan_dev; -+ -+ /* Verify the wan device is not already configured */ -+ wan_dev = airoha_get_wan_gdm_dev(eth); -+ if (wan_dev && wan_dev != dev) -+ return -EBUSY; -+ -+ switch (port->id) { -+ case AIROHA_GDM2_IDX: -+ dev->flags |= AIROHA_PRIV_F_WAN; -+ airoha_dev_set_qdma(dev); -+ break; -+ case AIROHA_GDM3_IDX: -+ case AIROHA_GDM4_IDX: { -+ int err; -+ -+ dev->flags |= AIROHA_PRIV_F_WAN; -+ airoha_dev_set_qdma(dev); -+ -+ err = airoha_enable_gdm2_loopback(dev); -+ if (err) { -+ dev->flags &= ~AIROHA_PRIV_F_WAN; -+ return err; -+ } -+ break; -+ } -+ default: -+ return -EOPNOTSUPP; -+ } -+ } else { -+ switch (port->id) { -+ case AIROHA_GDM3_IDX: -+ case AIROHA_GDM4_IDX: { -+ int err; -+ -+ err = airoha_disable_gdm2_loopback(dev); -+ if (err) -+ return err; -+ break; -+ } -+ default: -+ break; -+ } -+ -+ dev->flags &= ~AIROHA_PRIV_F_WAN; -+ airoha_dev_set_qdma(dev); -+ } -+ -+ return airoha_set_macaddr(dev, netdev->dev_addr); -+} -+ -+static const struct airoha_ethool_priv_flags airoha_eth_priv_flags[] = { -+ { "wan", airoha_dev_set_wan_flag }, -+}; -+#define AIROHA_PRIV_FLAGS_STR_LEN ARRAY_SIZE(airoha_eth_priv_flags) -+ - static void airoha_ethtool_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *info) - { -@@ -2530,6 +2648,7 @@ static void airoha_ethtool_get_drvinfo(s - - strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver)); - strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info)); -+ info->n_priv_flags = AIROHA_PRIV_FLAGS_STR_LEN; - } - - static void airoha_ethtool_get_mac_stats(struct net_device *netdev, -@@ -2594,6 +2713,56 @@ airoha_ethtool_get_rmon_stats(struct net - } while (u64_stats_fetch_retry(&port->stats.syncp, start)); - } - -+static int airoha_ethtool_set_priv_flags(struct net_device *netdev, u32 flags) -+{ -+ int i; -+ -+ for (i = 0; i < AIROHA_PRIV_FLAGS_STR_LEN; i++) { -+ int err; -+ -+ if (!airoha_eth_priv_flags[i].handler) -+ continue; -+ -+ err = airoha_eth_priv_flags[i].handler(netdev, flags); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static u32 airoha_ethtool_get_priv_flags(struct net_device *netdev) -+{ -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ -+ return dev->flags; -+} -+ -+static int airoha_ethtool_get_sset_count(struct net_device *netdev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_PRIV_FLAGS: -+ return AIROHA_PRIV_FLAGS_STR_LEN; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static void airoha_ethtool_get_strings(struct net_device *netdev, -+ u32 stringset, u8 *data) -+{ -+ int i; -+ -+ switch (stringset) { -+ case ETH_SS_PRIV_FLAGS: -+ for (i = 0; i < AIROHA_PRIV_FLAGS_STR_LEN; i++) -+ ethtool_puts(&data, airoha_eth_priv_flags[i].name); -+ break; -+ default: -+ break; -+ } -+} -+ - static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev, - int channel, enum tx_sched_mode mode, - const u16 *weights, u8 n_weights) -@@ -3315,6 +3484,10 @@ static const struct ethtool_ops airoha_e - .get_rmon_stats = airoha_ethtool_get_rmon_stats, - .get_link_ksettings = phy_ethtool_get_link_ksettings, - .get_link = ethtool_op_get_link, -+ .set_priv_flags = airoha_ethtool_set_priv_flags, -+ .get_priv_flags = airoha_ethtool_get_priv_flags, -+ .get_sset_count = airoha_ethtool_get_sset_count, -+ .get_strings = airoha_ethtool_get_strings, - }; - - static void airoha_mac_config(struct phylink_config *config, unsigned int mode, ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -402,6 +402,7 @@ - - #define REG_SRC_PORT_FC_MAP6 0x2298 - #define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3)) -+#define FC_MAP6_DEF_VALUE 0x1b1a1918 - - #define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 - diff --git a/target/linux/airoha/patches-6.12/920-13-net-airoha-Rework-MTU-configuration.patch b/target/linux/airoha/patches-6.12/920-13-net-airoha-Rework-MTU-configuration.patch deleted file mode 100644 index 072b50fe35c..00000000000 --- a/target/linux/airoha/patches-6.12/920-13-net-airoha-Rework-MTU-configuration.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 99e204d255c9b47a188dd79762b9406d9c5fed9b Mon Sep 17 00:00:00 2001 -Message-ID: <99e204d255c9b47a188dd79762b9406d9c5fed9b.1779348625.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Wed, 20 May 2026 17:16:39 +0200 -Subject: [PATCH 13/13] net: airoha: Rework MTU configuration - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 85 +++++++++++------------ - drivers/net/ethernet/airoha/airoha_eth.h | 1 + - drivers/net/ethernet/airoha/airoha_ppe.c | 8 +-- - drivers/net/ethernet/airoha/airoha_regs.h | 9 ++- - 4 files changed, 49 insertions(+), 54 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -185,10 +185,15 @@ static void airoha_fe_maccr_init(struct - { - int p; - -- for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) -+ for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) { - airoha_fe_set(eth, REG_GDM_FWD_CFG(p), - GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK | - GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK); -+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p), -+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -+ FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_RX_SIZE)); -+ } - - airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK, - FIELD_PREP(CDM_VLAN_MASK, 0x8100)); -@@ -1908,13 +1913,24 @@ static void airoha_update_hw_stats(struc - spin_unlock(&port->stats.lock); - } - -+static void airoha_dev_set_mtu(struct net_device *netdev) -+{ -+ struct airoha_gdm_dev *dev = netdev_priv(netdev); -+ -+ airoha_ppe_set_mtu(dev); -+ if (!airoha_is_lan_gdm_dev(dev)) -+ airoha_fe_rmw(dev->eth, REG_WAN_MTU0, -+ WAN_MTU0_MASK, -+ FIELD_PREP(WAN_MTU0_MASK, netdev->mtu)); -+} -+ - static int airoha_dev_open(struct net_device *netdev) - { -- int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN; - struct airoha_gdm_dev *dev = netdev_priv(netdev); - struct airoha_gdm_port *port = dev->port; -- u32 cur_len, pse_port = FE_PSE_PORT_PPE1; - struct airoha_qdma *qdma = dev->qdma; -+ u32 pse_port = FE_PSE_PORT_PPE1; -+ int err; - - if (port->id == AIROHA_GDM2_IDX && airoha_is_lan_gdm_dev(dev)) { - /* GDM2 can be used just as wan */ -@@ -1947,19 +1963,7 @@ static int airoha_dev_open(struct net_de - airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id), - GDM_STAG_EN_MASK); - -- cur_len = airoha_fe_get(qdma->eth, REG_GDM_LEN_CFG(port->id), -- GDM_LONG_LEN_MASK); -- if (!port->users || len > cur_len) { -- /* Opening a sibling net_device with a larger MTU updates the -- * MTU of already running devices. This is required to allow -- * multiple net_devices with different MTUs to share the same -- * GDM port. -- */ -- airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id), -- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -- FIELD_PREP(GDM_LONG_LEN_MASK, len)); -- } -+ airoha_dev_set_mtu(netdev); - port->users++; - - airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG, -@@ -1976,30 +1980,6 @@ static int airoha_dev_open(struct net_de - return 0; - } - --static void airoha_set_port_mtu(struct airoha_eth *eth, -- struct airoha_gdm_port *port) --{ -- u32 len = 0; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(port->devs); i++) { -- struct airoha_gdm_dev *dev = port->devs[i]; -- struct net_device *netdev; -- -- if (!dev) -- continue; -- -- netdev = dev->dev; -- if (netif_running(netdev)) -- len = max_t(u32, len, netdev->mtu); -- } -- len += ETH_HLEN + ETH_FCS_LEN; -- -- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id), -- GDM_LONG_LEN_MASK, -- FIELD_PREP(GDM_LONG_LEN_MASK, len)); --} -- - static int airoha_dev_stop(struct net_device *netdev) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -@@ -2013,7 +1993,7 @@ static int airoha_dev_stop(struct net_de - netdev_tx_reset_subqueue(netdev, i); - - if (--port->users) -- airoha_set_port_mtu(dev->eth, port); -+ airoha_ppe_set_mtu(dev); - else - airoha_set_gdm_port_fwd_cfg(qdma->eth, - REG_GDM_FWD_CFG(port->id), -@@ -2083,10 +2063,6 @@ static int airoha_enable_gdm2_loopback(s - FIELD_PREP(LPBK_CHAN_MASK, chan) | - LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK | - LBK_CHAN_MODE_MASK | LPBK_EN_MASK); -- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(AIROHA_GDM2_IDX), -- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, -- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | -- FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU)); - /* Forward the traffic to the proper GDM port */ - pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 - : FE_PSE_PORT_GDM4; -@@ -2270,7 +2246,7 @@ static int airoha_dev_change_mtu(struct - - WRITE_ONCE(netdev->mtu, mtu); - if (port->users) -- airoha_set_port_mtu(dev->eth, port); -+ airoha_dev_set_mtu(netdev); - - return 0; - } -@@ -2613,6 +2589,7 @@ static int airoha_dev_set_wan_flag(struc - default: - return -EOPNOTSUPP; - } -+ airoha_dev_set_mtu(netdev); - } else { - switch (port->id) { - case AIROHA_GDM3_IDX: ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -23,6 +23,7 @@ - #define AIROHA_MAX_DSA_PORTS 7 - #define AIROHA_MAX_NUM_RSTS 3 - #define AIROHA_MAX_MTU 9220 -+#define AIROHA_MAX_RX_SIZE 16128 - #define AIROHA_MAX_PACKET_SIZE 2048 - #define AIROHA_NUM_QOS_CHANNELS 4 - #define AIROHA_NUM_QOS_QUEUES 8 -@@ -706,6 +707,7 @@ int airoha_get_fe_port(struct airoha_gdm - bool airoha_is_valid_gdm_dev(struct airoha_eth *eth, - struct airoha_gdm_dev *dev); - -+void airoha_ppe_set_mtu(struct airoha_gdm_dev *dev); - void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport); - bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index); - void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb, ---- a/drivers/net/ethernet/airoha/airoha_ppe.c -+++ b/drivers/net/ethernet/airoha/airoha_ppe.c -@@ -98,6 +98,35 @@ void airoha_ppe_set_cpu_port(struct airo - __field_prep(DFT_CPORT_MASK(fport), fe_cpu_port)); - } - -+void airoha_ppe_set_mtu(struct airoha_gdm_dev *dev) -+{ -+ struct airoha_gdm_port *port = dev->port; -+ struct airoha_eth *eth = dev->eth; -+ int i, ppe_id, index; -+ u32 mtu = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) { -+ struct airoha_gdm_dev *d = port->devs[i]; -+ struct net_device *netdev; -+ -+ if (!d) -+ continue; -+ -+ if (d->qdma != dev->qdma) -+ continue; -+ -+ netdev = d->dev; -+ if (netif_running(netdev)) -+ mtu = max_t(u32, mtu, netdev->mtu); -+ } -+ -+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1); -+ index = port->id == AIROHA_GDM4_IDX ? 7 : port->id; -+ airoha_fe_rmw(eth, REG_PPE_MTU(ppe_id, index), -+ FP_EGRESS_MTU_MASK(index), -+ __field_prep(FP_EGRESS_MTU_MASK(index), mtu)); -+} -+ - static void airoha_ppe_hw_init(struct airoha_ppe *ppe) - { - u32 sram_ppe_num_data_entries = PPE_SRAM_NUM_ENTRIES, sram_num_entries; -@@ -116,8 +145,6 @@ static void airoha_ppe_hw_init(struct ai - PPE_RAM_NUM_ENTRIES_SHIFT(sram_ppe_num_data_entries); - - for (i = 0; i < eth->soc->num_ppe; i++) { -- int p; -- - airoha_fe_wr(eth, REG_PPE_TB_BASE(i), - ppe->foe_dma + sram_tb_size); - -@@ -167,15 +194,6 @@ static void airoha_ppe_hw_init(struct ai - airoha_fe_wr(eth, REG_PPE_HASH_SEED(i), PPE_HASH_SEED); - airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i), - PPE_FLOW_CFG_IP6_6RD_MASK); -- -- for (p = 0; p < ARRAY_SIZE(eth->ports); p++) -- airoha_fe_rmw(eth, REG_PPE_MTU(i, p), -- FP0_EGRESS_MTU_MASK | -- FP1_EGRESS_MTU_MASK, -- FIELD_PREP(FP0_EGRESS_MTU_MASK, -- AIROHA_MAX_MTU) | -- FIELD_PREP(FP1_EGRESS_MTU_MASK, -- AIROHA_MAX_MTU)); - } - - for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { -@@ -197,6 +215,7 @@ static void airoha_ppe_hw_init(struct ai - airoha_ppe_is_enabled(eth, 1); - fport = airoha_get_fe_port(dev); - airoha_ppe_set_cpu_port(dev, ppe_id, fport); -+ airoha_ppe_set_mtu(dev); - } - } - } ---- a/drivers/net/ethernet/airoha/airoha_regs.h -+++ b/drivers/net/ethernet/airoha/airoha_regs.h -@@ -341,9 +341,8 @@ - #define PPE_SRAM_TABLE_EN_MASK BIT(0) - - #define REG_PPE_MTU_BASE(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x304) --#define REG_PPE_MTU(_m, _n) (REG_PPE_MTU_BASE(_m) + ((_n) << 2)) --#define FP1_EGRESS_MTU_MASK GENMASK(29, 16) --#define FP0_EGRESS_MTU_MASK GENMASK(13, 0) -+#define REG_PPE_MTU(_m, _n) (REG_PPE_MTU_BASE(_m) + (((_n) / 2) << 2)) -+#define FP_EGRESS_MTU_MASK(_n) GENMASK(13 + (((_n) % 2) << 4), ((_n) % 2) << 4) - - #define REG_PPE_RAM_CTRL(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x31c) - #define PPE_SRAM_CTRL_ACK_MASK BIT(31) -@@ -404,6 +403,10 @@ - #define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3)) - #define FC_MAP6_DEF_VALUE 0x1b1a1918 - -+#define REG_WAN_MTU0 0x2300 -+#define WAN_MTU1_MASK GENMASK(29, 16) -+#define WAN_MTU0_MASK GENMASK(13, 0) -+ - #define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4 - - /* QDMA */ diff --git a/target/linux/airoha/patches-6.12/920-14-net-airoha-Better-handle-MIB-for-GDM-with-multiple-p.patch b/target/linux/airoha/patches-6.12/920-14-net-airoha-Better-handle-MIB-for-GDM-with-multiple-p.patch deleted file mode 100644 index 25db5b6661e..00000000000 --- a/target/linux/airoha/patches-6.12/920-14-net-airoha-Better-handle-MIB-for-GDM-with-multiple-p.patch +++ /dev/null @@ -1,415 +0,0 @@ -From 9652322e0b47eacfef497828f6476a2a3169fd13 Mon Sep 17 00:00:00 2001 -Message-ID: <9652322e0b47eacfef497828f6476a2a3169fd13.1779351672.git.lorenzo@kernel.org> -From: Christian Marangi -Date: Sat, 17 Jan 2026 14:46:12 +0100 -Subject: [PATCH] net: airoha: Better handle MIB for GDM with multiple port - attached - -In the context of a GDM that can have multiple port attached (GDM3/4) -the HW counter (MIB) are global for the GDM port. This cause duplicated -stats reported to the kernel for the related interface. - -The SoC supports a split MIB feature where each counter is tracked based -on the relevant HW channel (NBQ) to account for this scenario and -provide a way to select the related counter on accessing the MIB -registers. - -Enable this feature for GDM3 and GDM4 and configure the relevant HW -channel before updating the HW stats to report correct HW counter to the -kernel for the related interface. - -Also move the stats struct from port to dev since HW counter are -now specific to the network interface instead of the GDM port. - -Co-developed-by: Brown Huang -Signed-off-by: Brown Huang -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 191 +++++++++++++---------- - drivers/net/ethernet/airoha/airoha_eth.h | 7 +- - 2 files changed, 112 insertions(+), 86 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -612,6 +612,14 @@ static int airoha_fe_init(struct airoha_ - airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), - GDM_PAD_EN_MASK | GDM_STRIP_CRC_MASK); - -+ /* Enable split for MIB counters for GDM3 and GDM4 */ -+ airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX), -+ FE_GDM_TX_MIB_SPLIT_EN_MASK | -+ FE_GDM_RX_MIB_SPLIT_EN_MASK); -+ airoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM4_IDX), -+ FE_GDM_TX_MIB_SPLIT_EN_MASK | -+ FE_GDM_RX_MIB_SPLIT_EN_MASK); -+ - airoha_fe_crsn_qsel_init(eth); - - airoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK); -@@ -1768,149 +1776,169 @@ static void airoha_qdma_stop_napi(struct - } - } - --static void airoha_update_hw_stats(struct airoha_gdm_dev *dev) -+static void airoha_dev_get_hw_stats(struct airoha_gdm_dev *dev) - { - struct airoha_gdm_port *port = dev->port; - struct airoha_eth *eth = dev->eth; - u32 val, i = 0; - -- spin_lock(&port->stats.lock); -- u64_stats_update_begin(&port->stats.syncp); -+ u64_stats_update_begin(&dev->stats.syncp); -+ -+ /* Read relevant MIB for GDM with multiple port attached */ -+ if (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX) -+ airoha_fe_rmw(eth, REG_FE_GDM_MIB_CFG(port->id), -+ FE_TX_MIB_ID_MASK | FE_RX_MIB_ID_MASK, -+ FIELD_PREP(FE_TX_MIB_ID_MASK, dev->nbq) | -+ FIELD_PREP(FE_RX_MIB_ID_MASK, dev->nbq)); - - /* TX */ - val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_H(port->id)); -- port->stats.tx_ok_pkts += ((u64)val << 32); -+ dev->stats.tx_ok_pkts += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_PKT_CNT_L(port->id)); -- port->stats.tx_ok_pkts += val; -+ dev->stats.tx_ok_pkts += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_H(port->id)); -- port->stats.tx_ok_bytes += ((u64)val << 32); -+ dev->stats.tx_ok_bytes += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_OK_BYTE_CNT_L(port->id)); -- port->stats.tx_ok_bytes += val; -+ dev->stats.tx_ok_bytes += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_DROP_CNT(port->id)); -- port->stats.tx_drops += val; -+ dev->stats.tx_drops += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_BC_CNT(port->id)); -- port->stats.tx_broadcast += val; -+ dev->stats.tx_broadcast += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_MC_CNT(port->id)); -- port->stats.tx_multicast += val; -+ dev->stats.tx_multicast += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_RUNT_CNT(port->id)); -- port->stats.tx_len[i] += val; -+ dev->stats.tx_len[i] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -+ dev->stats.tx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_E64_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -+ dev->stats.tx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -+ dev->stats.tx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L64_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -+ dev->stats.tx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -+ dev->stats.tx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L127_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -+ dev->stats.tx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -+ dev->stats.tx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L255_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -+ dev->stats.tx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -+ dev->stats.tx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L511_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -+ dev->stats.tx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_H(port->id)); -- port->stats.tx_len[i] += ((u64)val << 32); -+ dev->stats.tx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_L1023_CNT_L(port->id)); -- port->stats.tx_len[i++] += val; -+ dev->stats.tx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_TX_ETH_LONG_CNT(port->id)); -- port->stats.tx_len[i++] += val; -+ dev->stats.tx_len[i++] += val; - - /* RX */ - val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_H(port->id)); -- port->stats.rx_ok_pkts += ((u64)val << 32); -+ dev->stats.rx_ok_pkts += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_PKT_CNT_L(port->id)); -- port->stats.rx_ok_pkts += val; -+ dev->stats.rx_ok_pkts += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_H(port->id)); -- port->stats.rx_ok_bytes += ((u64)val << 32); -+ dev->stats.rx_ok_bytes += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_OK_BYTE_CNT_L(port->id)); -- port->stats.rx_ok_bytes += val; -+ dev->stats.rx_ok_bytes += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_DROP_CNT(port->id)); -- port->stats.rx_drops += val; -+ dev->stats.rx_drops += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_BC_CNT(port->id)); -- port->stats.rx_broadcast += val; -+ dev->stats.rx_broadcast += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_MC_CNT(port->id)); -- port->stats.rx_multicast += val; -+ dev->stats.rx_multicast += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ERROR_DROP_CNT(port->id)); -- port->stats.rx_errors += val; -+ dev->stats.rx_errors += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_CRC_ERR_CNT(port->id)); -- port->stats.rx_crc_error += val; -+ dev->stats.rx_crc_error += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_OVERFLOW_DROP_CNT(port->id)); -- port->stats.rx_over_errors += val; -+ dev->stats.rx_over_errors += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_FRAG_CNT(port->id)); -- port->stats.rx_fragment += val; -+ dev->stats.rx_fragment += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_JABBER_CNT(port->id)); -- port->stats.rx_jabber += val; -+ dev->stats.rx_jabber += val; - - i = 0; - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_RUNT_CNT(port->id)); -- port->stats.rx_len[i] += val; -+ dev->stats.rx_len[i] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -+ dev->stats.rx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_E64_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -+ dev->stats.rx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -+ dev->stats.rx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L64_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -+ dev->stats.rx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -+ dev->stats.rx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L127_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -+ dev->stats.rx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -+ dev->stats.rx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L255_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -+ dev->stats.rx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -+ dev->stats.rx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L511_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -+ dev->stats.rx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_H(port->id)); -- port->stats.rx_len[i] += ((u64)val << 32); -+ dev->stats.rx_len[i] += ((u64)val << 32); - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_L1023_CNT_L(port->id)); -- port->stats.rx_len[i++] += val; -+ dev->stats.rx_len[i++] += val; - - val = airoha_fe_rr(eth, REG_FE_GDM_RX_ETH_LONG_CNT(port->id)); -- port->stats.rx_len[i++] += val; -+ dev->stats.rx_len[i++] += val; -+ -+ u64_stats_update_end(&dev->stats.syncp); -+} -+ -+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev) -+{ -+ struct airoha_gdm_port *port = dev->port; -+ int i; -+ -+ spin_lock(&port->stats_lock); -+ -+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) { -+ if (port->devs[i]) -+ airoha_dev_get_hw_stats(port->devs[i]); -+ } - -- /* reset mib counters */ -- airoha_fe_set(eth, REG_FE_GDM_MIB_CLEAR(port->id), -+ /* Reset MIB counters */ -+ airoha_fe_set(dev->eth, REG_FE_GDM_MIB_CLEAR(port->id), - FE_GDM_MIB_RX_CLEAR_MASK | FE_GDM_MIB_TX_CLEAR_MASK); - -- u64_stats_update_end(&port->stats.syncp); -- spin_unlock(&port->stats.lock); -+ spin_unlock(&port->stats_lock); - } - - static void airoha_dev_set_mtu(struct net_device *netdev) -@@ -2220,23 +2248,22 @@ static void airoha_dev_get_stats64(struc - struct rtnl_link_stats64 *storage) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - unsigned int start; - - airoha_update_hw_stats(dev); - do { -- start = u64_stats_fetch_begin(&port->stats.syncp); -- storage->rx_packets = port->stats.rx_ok_pkts; -- storage->tx_packets = port->stats.tx_ok_pkts; -- storage->rx_bytes = port->stats.rx_ok_bytes; -- storage->tx_bytes = port->stats.tx_ok_bytes; -- storage->multicast = port->stats.rx_multicast; -- storage->rx_errors = port->stats.rx_errors; -- storage->rx_dropped = port->stats.rx_drops; -- storage->tx_dropped = port->stats.tx_drops; -- storage->rx_crc_errors = port->stats.rx_crc_error; -- storage->rx_over_errors = port->stats.rx_over_errors; -- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); -+ start = u64_stats_fetch_begin(&dev->stats.syncp); -+ storage->rx_packets = dev->stats.rx_ok_pkts; -+ storage->tx_packets = dev->stats.tx_ok_pkts; -+ storage->rx_bytes = dev->stats.rx_ok_bytes; -+ storage->tx_bytes = dev->stats.tx_ok_bytes; -+ storage->multicast = dev->stats.rx_multicast; -+ storage->rx_errors = dev->stats.rx_errors; -+ storage->rx_dropped = dev->stats.rx_drops; -+ storage->tx_dropped = dev->stats.tx_drops; -+ storage->rx_crc_errors = dev->stats.rx_crc_error; -+ storage->rx_over_errors = dev->stats.rx_over_errors; -+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start)); - } - - static int airoha_dev_change_mtu(struct net_device *netdev, int mtu) -@@ -2632,20 +2659,19 @@ static void airoha_ethtool_get_mac_stats - struct ethtool_eth_mac_stats *stats) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; - unsigned int start; - - airoha_update_hw_stats(dev); - do { -- start = u64_stats_fetch_begin(&port->stats.syncp); -- stats->FramesTransmittedOK = port->stats.tx_ok_pkts; -- stats->OctetsTransmittedOK = port->stats.tx_ok_bytes; -- stats->MulticastFramesXmittedOK = port->stats.tx_multicast; -- stats->BroadcastFramesXmittedOK = port->stats.tx_broadcast; -- stats->FramesReceivedOK = port->stats.rx_ok_pkts; -- stats->OctetsReceivedOK = port->stats.rx_ok_bytes; -- stats->BroadcastFramesReceivedOK = port->stats.rx_broadcast; -- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); -+ start = u64_stats_fetch_begin(&dev->stats.syncp); -+ stats->FramesTransmittedOK = dev->stats.tx_ok_pkts; -+ stats->OctetsTransmittedOK = dev->stats.tx_ok_bytes; -+ stats->MulticastFramesXmittedOK = dev->stats.tx_multicast; -+ stats->BroadcastFramesXmittedOK = dev->stats.tx_broadcast; -+ stats->FramesReceivedOK = dev->stats.rx_ok_pkts; -+ stats->OctetsReceivedOK = dev->stats.rx_ok_bytes; -+ stats->BroadcastFramesReceivedOK = dev->stats.rx_broadcast; -+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start)); - } - - static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = { -@@ -2665,8 +2691,7 @@ airoha_ethtool_get_rmon_stats(struct net - const struct ethtool_rmon_hist_range **ranges) - { - struct airoha_gdm_dev *dev = netdev_priv(netdev); -- struct airoha_gdm_port *port = dev->port; -- struct airoha_hw_stats *hw_stats = &port->stats; -+ struct airoha_hw_stats *hw_stats = &dev->stats; - unsigned int start; - - BUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) != -@@ -2679,7 +2704,7 @@ airoha_ethtool_get_rmon_stats(struct net - do { - int i; - -- start = u64_stats_fetch_begin(&port->stats.syncp); -+ start = u64_stats_fetch_begin(&dev->stats.syncp); - stats->fragments = hw_stats->rx_fragment; - stats->jabbers = hw_stats->rx_jabber; - for (i = 0; i < ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1; -@@ -2687,7 +2712,7 @@ airoha_ethtool_get_rmon_stats(struct net - stats->hist[i] = hw_stats->rx_len[i]; - stats->hist_tx[i] = hw_stats->tx_len[i]; - } -- } while (u64_stats_fetch_retry(&port->stats.syncp, start)); -+ } while (u64_stats_fetch_retry(&dev->stats.syncp, start)); - } - - static int airoha_ethtool_set_priv_flags(struct net_device *netdev, u32 flags) -@@ -3695,6 +3720,7 @@ static int airoha_alloc_gdm_device(struc - - netdev->dev.of_node = of_node_get(np); - dev = netdev_priv(netdev); -+ u64_stats_init(&dev->stats.syncp); - dev->dev = netdev; - dev->port = port; - dev->eth = eth; -@@ -3743,9 +3769,8 @@ static int airoha_alloc_gdm_port(struct - if (!port) - return -ENOMEM; - -- u64_stats_init(&port->stats.syncp); -- spin_lock_init(&port->stats.lock); - port->id = id; -+ spin_lock_init(&port->stats_lock); - eth->ports[p] = port; - - err = airoha_metadata_dst_alloc(port); ---- a/drivers/net/ethernet/airoha/airoha_eth.h -+++ b/drivers/net/ethernet/airoha/airoha_eth.h -@@ -228,8 +228,6 @@ struct airoha_tx_irq_queue { - }; - - struct airoha_hw_stats { -- /* protect concurrent hw_stats accesses */ -- spinlock_t lock; - struct u64_stats_sync syncp; - - /* get_stats64 */ -@@ -573,6 +571,8 @@ struct airoha_gdm_dev { - - u32 flags; - int nbq; -+ -+ struct airoha_hw_stats stats; - }; - - struct airoha_gdm_port { -@@ -580,7 +580,8 @@ struct airoha_gdm_port { - int id; - int users; - -- struct airoha_hw_stats stats; -+ /* protect concurrent hw_stats accesses */ -+ spinlock_t stats_lock; - - struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; - }; diff --git a/target/linux/airoha/patches-6.12/920-15-net-airoha-fix-wrong-airoha_get_fe_port.patch b/target/linux/airoha/patches-6.12/920-15-net-airoha-fix-wrong-airoha_get_fe_port.patch deleted file mode 100644 index 75a49306c2c..00000000000 --- a/target/linux/airoha/patches-6.12/920-15-net-airoha-fix-wrong-airoha_get_fe_port.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 1e596dac503da44a9fcd3e2654a4963db3e2ee6a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 28 Jan 2026 02:38:24 +0100 -Subject: [PATCH] net: airoha: fix wrong airoha_get_fe_port() - -It seems the SDK where the airoha_get_fe_port() logic was taken was -actually wrong and the AN7583 SoC doesn't have such difference. Instead -it does follow the same port order of AN7581 SoC. - -Drop the switch case and apply the same condition on both AN7581 and -AN7583 SoC. - -Fixes: e4e5ce823bdd ("net: airoha: Add AN7583 SoC support") -Signed-off-by: Christian Marangi ---- - drivers/net/ethernet/airoha/airoha_eth.c | 14 ++------------ - 1 file changed, 2 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/airoha/airoha_eth.c -+++ b/drivers/net/ethernet/airoha/airoha_eth.c -@@ -2345,17 +2345,9 @@ static u32 airoha_get_dsa_tag(struct sk_ - int airoha_get_fe_port(struct airoha_gdm_dev *dev) - { - struct airoha_gdm_port *port = dev->port; -- struct airoha_eth *eth = dev->eth; - -- switch (eth->soc->version) { -- case 0x7583: -- return port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 -- : port->id; -- case 0x7581: -- default: -- return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4 -- : port->id; -- } -+ return port->id == AIROHA_GDM4_IDX ? FE_PSE_PORT_GDM4 -+ : port->id; - } - - static int airoha_dev_set_features(struct net_device *netdev, -- 2.47.3